我對 XML 和 python 有點陌生。下面是我試圖引入 python 以最終寫入 SQL Server db 的大型 XML 檔案的縮減版本。
<?xml version="1.0" encoding="utf-8"?>
<MyOrgRefData:OrgRefData xmlns:MyOrgRefData="http://refdata.org/org/v2-0-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://refdata.org/org/v2-0-0/MyOrgRefData.xsd">
<Manifest>
<Version value="2-0-0" />
<PublicationType value="Full" />
<PublicationSource value="TEST123" />
<PublicationDate value="2022-05-23" />
<PublicationSeqNum value="1659" />
<FileCreationDateTime value="2022-05-23T22:14:47" />
<RecordCount value="287654" />
<ContentDescription value="FullFile_20220523" />
<PrimaryRoleScope>
<PrimaryRole id="123" displayName="Free beer for me" />
<PrimaryRole id="456" displayName="Free air for you" />
</PrimaryRoleScope>
</Manifest>
<CodeSystems>
<CodeSystem name="OrganisationRecordClass" oid="1.2.3.4.5">
<concept id="RC2" code="2" displayName="World1" />
<concept id="RC1" code="1" displayName="World2" />
</CodeSystem>
<CodeSystem name="OrganisationRole" oid="5.4.7.8">
<concept id="B1ng0" code="179" displayName="BoomBastic" />
<concept id="R2D2a" code="180" displayName="Fantastic" />
</CodeSystem>
</CodeSystems>
</MyOrgRefData:OrgRefData>
我已經嘗試過使用 lxml、pandas.read_xml、xml.etree,但我無法理解如何獲得我想要的東西。
理想情況下,我想將Manifest拉入準備發送到 SQL (pd.to_sql()) 的資料幀中。我也會對CodeSystems做同樣的事情,但要分開做。(還有其他部分,但我將它們剪掉以縮短)
例如,使用熊貓讀入,我只能得到一個包含值的列。但我想在值旁邊的列中包含標簽(版本、出版物型別、出版物來源等),或者讓它們作為列標題和值跨行旋轉。
dataFolder = '/Some/directory'
df_bulk = pd.read_xml(
dataFolder 'Data_Full_20220523.xml',
xpath='//Manifest/*',
attrs_only=True ,
)
df_bulk.head()
這是我得到的輸出:
| 索引 | 價值 |
|---|---|
| 0 | 2-0-0 |
| 1 | 滿的 |
| 2 | 測驗123 |
| 3 | 2022-05-23 |
| 4 | 1659 |
| 5 | 2022-05-23T22:14:47 |
| 6 | 287654 |
| 7 | FullFile_20220523 |
理想情況下,我想:
| 索引 | 價值 |
|---|---|
| 版本 | 2-0-0 |
| 出版物型別 | 滿的 |
| 出版來源 | 測驗123 |
| 發布日期 | 2022-05-23 |
| 發表序列號 | 1659 |
| 檔案創建日期時間 | 2022-05-23T22:14:47 |
| 檔案創建日期時間 | 287654 |
| 內容描述 | FullFile_20220523 |
你們中的老鷹眼會注意到我遺漏了PrimaryRoleScope。理想情況下,我也希望在它自己的資料框中單獨處理它。但是我不確定在拉入 Manifest 部分的其余部分時如何排除它。
非常感謝你讀到這里,更感謝你的幫助。
uj5u.com熱心網友回復:
一種可能性是stylesheet在處理 XML 資料之前使用該引數在內部使用 XSLT 對其進行轉換。
因此,您的代碼可能如下所示:
dataFolder = '/Some/directory'
df_bulk = pd.read_xml(
dataFolder 'Data_Full_20220523.xml',
stylesheet='transform.xslt',
xpath='/Root/Item',
attrs_only=True ,
)
print(df_bulk.head(10))
transform.xml要傳遞給的樣式表( )read_xml可以是(需要lxml)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<Root><xsl:apply-templates /></Root>
</xsl:template>
<xsl:template match="//Manifest/*[not(self::PrimaryRoleScope)]">
<Item name="{name()}" value="{@value}" />
</xsl:template>
</xsl:stylesheet>
在此示例中,創建了一個如下所示的新 XML。它是中間 XML 并且未顯示,但xpath=必須相應地設定上面的引數。
<Root>
<Item name="Version" value="2-0-0"/>
<Item name="PublicationType" value="Full"/>
<Item name="PublicationSource" value="TEST123"/>
<Item name="PublicationDate" value="2022-05-23"/>
<Item name="PublicationSeqNum" value="1659"/>
<Item name="FileCreationDateTime" value="2022-05-23T22:14:47"/>
<Item name="RecordCount" value="287654"/>
<Item name="ContentDescription" value="FullFile_20220523"/>
</Root>
最后的輸出是
name value
0 Version 2-0-0
1 PublicationType Full
2 PublicationSource TEST123
3 PublicationDate 2022-05-23
4 PublicationSeqNum 1659
5 FileCreationDateTime 2022-05-23T22:14:47
6 RecordCount 287654
7 ContentDescription FullFile_20220523
上述方法僅使用屬性,但如果您愿意,也可以使用 XSLT 創建元素結構。在這種情況下,將一個模板更改為
<xsl:template match="//Manifest/*[not(self::PrimaryRoleScope)]">
<Item>
<name><xsl:value-of select="name()" /></name>
<value><xsl:value-of select="@value" /></value>
</Item>
</xsl:template>
和你的python代碼
dataFolder = '/Some/directory'
df_bulk = pd.read_xml(
dataFolder 'Data_Full_20220523.xml',
stylesheet='transform.xslt',
xpath='/Root/Item',
)
print(df_bulk.head(10))
輸出是一樣的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/492125.html
