在给定的标签处将 XML 文件拆分为多个

Posted

技术标签:

【中文标题】在给定的标签处将 XML 文件拆分为多个【英文标题】:Splitting XML file into multiple at given tags 【发布时间】:2016-07-09 09:05:58 【问题描述】:

我想将一个 XML 文件拆分为多个文件。我的工作站非常受限于带有 Xalan 2.7.1 的 Eclipse Mars。

我也可以使用 Python,但以前从未使用过。

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <row>
        <NAME>Doe</NAME>
        <FIRSTNAME>Jon</FIRSTNAME>
        <GENDER>M</GENDER>
    </row>
    <row>
        <NAME>Mustermann</NAME>
        <FIRSTNAME>Max</FIRSTNAME>
        <GENDER>M</GENDER>
    </row>
</root>

我怎样才能让它们看起来像这样

<?xml version="1.0" encoding="UTF-8"?>
    <root>
        <row>
            <NAME>Doe</NAME>
            <FIRSTNAME>Jon</FIRSTNAME>
            <GENDER>M</GENDER>
        </row>
    </root>

我需要一个带有标题的文件中的每个“行”数据。上面的数据只是一个例子。大多数“行”数据有 16 个属性,但不时变化。

【问题讨论】:

你是用java还是python做拆分? 【参考方案1】:

使用 Python 元素树。

创建一个文件,例如xmlsplitter.py。添加下面的代码(其中 file.xml 是您的 xml 文件,并假设每一行都有一个唯一的 NAME 元素。)。

import xml.etree.ElementTree as ET
context = ET.iterparse('file.xml', events=('end', ))
for event, elem in context:
    if elem.tag == 'row':
        title = elem.find('NAME').text
        filename = format(title + ".xml")
        with open(filename, 'wb') as f:
            f.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
            f.write(ET.tostring(elem))

运行它
python xmlsplitter.py

或者如果名称不是唯一的:

import xml.etree.ElementTree as ET
context = ET.iterparse('file.xml', events=('end', ))
index = 0
for event, elem in context:
    if elem.tag == 'row':
        index += 1
        filename = format(str(index) + ".xml")
        with open(filename, 'wb') as f:
            f.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
            f.write(ET.tostring(elem))

【讨论】:

谢谢 Dan-Dev,我稍微编辑了您的代码并附加了“根”标签。还有一个问题,如何将 .xml 附加到输出文件? 我在一分钟前对其进行了编辑,现在显示为:文件名 = 格式(标题 + “.xml”)。如果您使用编辑后的代码再次运行它,则应该将文件扩展名 .xml 附加到您的文件中 好的,还有一个问题。一些 NAME 出现不止一次。是否可以遍历以例如开头的输出文件名1.xml? 编辑在“或者如果名称不唯一:”之后添加代码【参考方案2】:

这是完美运行的代码。

import xml.etree.ElementTree as ET

context = ET.iterparse('filname.xml', events=('end', ))
for event, elem in context:
if elem.tag == 'row':
    title = elem.find('NAME').text
    filename = format(title + ".xml")
    with open(filename, 'wb') as f:
        f.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
        f.write("<root>\n")
        f.write(ET.tostring(elem))
        f.write("</root>")

【讨论】:

看起来在 Python3 中你需要写这样的字符串 f.write(b"\n") note b letter before "\n"【参考方案3】:

有一个很棒的工具 http://xmlstar.sourceforge.net/docs.php 可以用 xml 做很多事情(但它不是 pythonic)。

假设您有一个包含上述数据的1.xml 文件。并且您需要将其拆分为名称为 NNN.xml 且元素为 /root/row 的单独文件。

只需在 shell 中调用:

    $ for ((i=1; i<=`xmlstarlet sel -t -v 'count(/root/row)'  1.xml`; i++)); do \
          echo '<?xml version="1.0" encoding="UTF-8"?><root>' > NAME.xml;
          NAME=$(xmlstarlet sel -t -m '/root/row[position()='$i']' -v './NAME' 1.xml); \
          xmlstarlet sel -t -m '/root/row[position()='$i']' -c . -n 1.xml >> $NAME.xml; \
          echo '</root>' >> NAME.xml
       done

现在你有一堆像 Joe.xml 这样的 xml 文件

【讨论】:

以上是关于在给定的标签处将 XML 文件拆分为多个的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 在多个索引处将 Arraylist 拆分为多个部分

在每个谓词 scala 处将字符串列表拆分为多个列表

XSLT - 根据长度很好地将长地址拆分为多个标签

C# 将 XML 文件从给定标签解析为对象

在 SQL 中使用 xml 标签拆分字符串

在给定偏移量处将音频剪辑插入原始音频文件