从一个文件解析特定的 XML 属性并将其附加到另一个文件中,前提是第二个文件中存在另一个属性
Parse specific XML attribute from one file and append it to another iff another attribute is present in the second file
我有三个 XML 文件(下面的示例)。我用它们各自的 audioId
属性值命名了这些文件。因此,有问题的文件将被称为 93.xml
和 2137.xml
:
93.xml:
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0" Use="P,L" audioId="93" />
2173.xml:
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0" Use="P,L" audioId="2137" />
mainDataSet.xml:
<word id="2137" title="over" level="1" grouping="Sight Words" YRule="0" MagicE="0" SoftC="0" doublevowel="0" longvowel="0" displayorder="101" silentletters="0"/>
文件 mainDataSet.xml
包含约 3,000 个条目。出于这个问题的目的,我只提供了其中的一个条目。
我的问题是,如果 id
在两个文件中都匹配(或者即使 mainDataSet.xml
中的 id
与文件 name 匹配)。例如,在我提供的样本中,输出应该是:
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0" Use="P,L" audioId="2137" title="over" />
要从 mainDataSet.xml
解析我的 XML,我目前正在做:
e = xml.etree.ElementTree.parse('mainDataSet.xml').getroot()
for atype in e.findall('word'):
print(atype.get('title'))
要添加属性,请使用 .attrib
字典。这是一个循环遍历 mainDataSet.xml
内的 word
元素的示例代码,检索 id
属性值,解析适当的 XML 文件(93.xml
和 2173.xml
在这种情况下),更新 word
元素并将树转储回文件:
import xml.etree.ElementTree as ET
e = ET.parse('mainDataSet.xml').getroot()
for word in e.findall('word'):
word_id = word.attrib.get("id")
if word_id:
filename = "%s.xml" % word_id
e_word = ET.parse(filename)
e_word.getroot().attrib['title'] = word.attrib.get('title')
e_word.write(filename)
我用过的示例 mainDataSet.xml
:
<words>
<word id="2137" title="over" level="1" grouping="Sight Words" YRule="0" MagicE="0" SoftC="0" doublevowel="0" longvowel="0" displayorder="101" silentletters="0"/>
<word id="93" title="something else" level="1" grouping="Sight Words" YRule="0" MagicE="0" SoftC="0" doublevowel="0" longvowel="0" displayorder="101" silentletters="0"/>
</words>
这是我在 运行 脚本之后得到的:
93.xml
:
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0" Use="P,L" audioId="93" title="something else" />
2173.xml
:
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0" Use="P,L" audioId="2137" title="over" />
对于 OP 或未来的读者,考虑一个 XSLT 1.0 解决方案,Python 可以 运行 使用 lxml
模块。作为信息,XSLT is a special purpose language (whose script is a well-formed xml file) designed to manipulate XML files. The script is portable to other general purpose languages (Java, PHP, C#), XSLT processors (Saxon, Xalan), even command line interpreters (Bash, PowerShell). Specifically, for this question, XSLT maintains the document()
函数可以访问外部 xml 文件中的节点以进行比较,如 ids。
输入 (添加根标签)
mainDataSet.xml
<root>
<word id="2137" title="over" level="1" grouping="Sight Words" YRule="0"
MagicE="0" SoftC="0" doublevowel="0" longvowel="0"
displayorder="101" silentletters="0"/>
</root>
2137.xml
<root>
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7"
Stage="0" Use="P,L" audioId="2137" />
</root>
93.xml
<root>
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7"
Stage="0" Use="P,L" audioId="93" />
</root>
XSLT 脚本 (在外部保存为 .xsl;在 .py 中读取;假定所有 XML 文件都在同一目录中)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="word"/>
</xsl:copy>
</xsl:template>
<xsl:template match="word">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:if test="@audioId = document('mainDataSet.xml')/root/word/@id">
<xsl:attribute name="title">
<xsl:value-of select="document('mainDataSet.xml')/root/word/@title"/>
</xsl:attribute>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Python 脚本
import lxml.etree as ET
# LOAD XML AND XSL
xslt = ET.parse('XSLTScript.xsl')
for i in ['2137', '93']:
dom = ET.parse('{}.xml'.format(i))
# TRANSFORM XML
transform = ET.XSLT(xslt)
newdom = transform(dom)
# PRETTY PRINT OUTPUT
tree_out = ET.tostring(newdom, encoding='UTF-8', pretty_print=True)
print(tree_out.decode("utf-8"))
# SAVE TO FILE
xmlfile = open('{}.xml'.format(i),'wb')
xmlfile.write(tree_out)
xmlfile.close()
输出 (使用发布的数据)
2173.xml
<root>
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0"
Use="P,L" audioId="2137" title="over"/>
</root>
93.xml
<root>
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0"
Use="P,L" audioId="93"/>
</root>
我有三个 XML 文件(下面的示例)。我用它们各自的 audioId
属性值命名了这些文件。因此,有问题的文件将被称为 93.xml
和 2137.xml
:
93.xml:
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0" Use="P,L" audioId="93" />
2173.xml:
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0" Use="P,L" audioId="2137" />
mainDataSet.xml:
<word id="2137" title="over" level="1" grouping="Sight Words" YRule="0" MagicE="0" SoftC="0" doublevowel="0" longvowel="0" displayorder="101" silentletters="0"/>
文件 mainDataSet.xml
包含约 3,000 个条目。出于这个问题的目的,我只提供了其中的一个条目。
我的问题是,如果 id
在两个文件中都匹配(或者即使 mainDataSet.xml
中的 id
与文件 name 匹配)。例如,在我提供的样本中,输出应该是:
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0" Use="P,L" audioId="2137" title="over" />
要从 mainDataSet.xml
解析我的 XML,我目前正在做:
e = xml.etree.ElementTree.parse('mainDataSet.xml').getroot()
for atype in e.findall('word'):
print(atype.get('title'))
要添加属性,请使用 .attrib
字典。这是一个循环遍历 mainDataSet.xml
内的 word
元素的示例代码,检索 id
属性值,解析适当的 XML 文件(93.xml
和 2173.xml
在这种情况下),更新 word
元素并将树转储回文件:
import xml.etree.ElementTree as ET
e = ET.parse('mainDataSet.xml').getroot()
for word in e.findall('word'):
word_id = word.attrib.get("id")
if word_id:
filename = "%s.xml" % word_id
e_word = ET.parse(filename)
e_word.getroot().attrib['title'] = word.attrib.get('title')
e_word.write(filename)
我用过的示例 mainDataSet.xml
:
<words>
<word id="2137" title="over" level="1" grouping="Sight Words" YRule="0" MagicE="0" SoftC="0" doublevowel="0" longvowel="0" displayorder="101" silentletters="0"/>
<word id="93" title="something else" level="1" grouping="Sight Words" YRule="0" MagicE="0" SoftC="0" doublevowel="0" longvowel="0" displayorder="101" silentletters="0"/>
</words>
这是我在 运行 脚本之后得到的:
93.xml
:<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0" Use="P,L" audioId="93" title="something else" />
2173.xml
:<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0" Use="P,L" audioId="2137" title="over" />
对于 OP 或未来的读者,考虑一个 XSLT 1.0 解决方案,Python 可以 运行 使用 lxml
模块。作为信息,XSLT is a special purpose language (whose script is a well-formed xml file) designed to manipulate XML files. The script is portable to other general purpose languages (Java, PHP, C#), XSLT processors (Saxon, Xalan), even command line interpreters (Bash, PowerShell). Specifically, for this question, XSLT maintains the document()
函数可以访问外部 xml 文件中的节点以进行比较,如 ids。
输入 (添加根标签)
mainDataSet.xml
<root>
<word id="2137" title="over" level="1" grouping="Sight Words" YRule="0"
MagicE="0" SoftC="0" doublevowel="0" longvowel="0"
displayorder="101" silentletters="0"/>
</root>
2137.xml
<root>
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7"
Stage="0" Use="P,L" audioId="2137" />
</root>
93.xml
<root>
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7"
Stage="0" Use="P,L" audioId="93" />
</root>
XSLT 脚本 (在外部保存为 .xsl;在 .py 中读取;假定所有 XML 文件都在同一目录中)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="word"/>
</xsl:copy>
</xsl:template>
<xsl:template match="word">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:if test="@audioId = document('mainDataSet.xml')/root/word/@id">
<xsl:attribute name="title">
<xsl:value-of select="document('mainDataSet.xml')/root/word/@title"/>
</xsl:attribute>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Python 脚本
import lxml.etree as ET
# LOAD XML AND XSL
xslt = ET.parse('XSLTScript.xsl')
for i in ['2137', '93']:
dom = ET.parse('{}.xml'.format(i))
# TRANSFORM XML
transform = ET.XSLT(xslt)
newdom = transform(dom)
# PRETTY PRINT OUTPUT
tree_out = ET.tostring(newdom, encoding='UTF-8', pretty_print=True)
print(tree_out.decode("utf-8"))
# SAVE TO FILE
xmlfile = open('{}.xml'.format(i),'wb')
xmlfile.write(tree_out)
xmlfile.close()
输出 (使用发布的数据)
2173.xml
<root>
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0"
Use="P,L" audioId="2137" title="over"/>
</root>
93.xml
<root>
<word BloomsTaxonomy="1,2,3" DictationGroupid="i-e combination List 7" Stage="0"
Use="P,L" audioId="93"/>
</root>