首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python中使用xslt合并多个xml

在Python中使用xslt合并多个xml
EN

Stack Overflow用户
提问于 2017-11-19 12:08:25
回答 1查看 422关注 0票数 0

我在一个目录中有100个xml文件。xml的结构完全相同。但是,我希望将xml的一些节点添加到一起,并保留其余的节点。

示例xml 1

代码语言:javascript
复制
<?xml-stylesheet type='text/xsl' href='image_metadata_stylesheet.xsl'?>
<dataset>
<name>imglab dataset</name>
<comment>Created by imglab tool.</comment>
<images>
<image file='/home/orcl/user102339/Area123/Geo_Tag_0812-0420.jpg'></image>
<image file='/home/orcl/user102339/Area123/Geo_Tag_0812-0544.jpg'>
<box top='343' left='72' width='92' height='29'>
<label>LBS_Marks
</label></box></image>
<image file='/home/orcl/user102339/Area123/Geo_Tag_0812-0489.jpg'></image>
</images>
</dataset>

示例xml 2

代码语言:javascript
复制
<?xml-stylesheet type='text/xsl' href='image_metadata_stylesheet.xsl'?>
<dataset>
<name>imglab dataset</name>
<comment>Created by imglab tool.</comment>
<images>
<image file="/home/orcl/user102339/Area123/Geo_Tag_0812-0420.jpg">
    <box top="505" left="326" width="59" height="32">
                <label>SBS_Marks</label>
            </box>
    </image>
<image file="/home/orcl/user102339/Area123/Geo_Tag_0812-0544.jpg">
    <box top="507" left="331" width="50" height="27">
                <label>SBS_Marks</label>
            </box>
    </image>
<image file="/home/orcl/user102339/Area123/Geo_Tag_0812-0489.jpg">
    <box top="509" left="330" width="51" height="25">
                <label>SBS_Marks</label>
            </box>
    </image>
</images>
</dataset>

在这两组数据中,图像是相同的,但是标记是不同的。例如,在第一示例集中,第一图像0420.jpg不具有与其相关联的任何框标记,而第二个文件中的相同图像具有带有标签SBS_Marks的框标记。我试图将这些文件合并在一起,这样,对于每一幅图像,我只能得到方框坐标和标签。例如,所需的输出如下:

代码语言:javascript
复制
<?xml-stylesheet type='text/xsl' href='image_metadata_stylesheet.xsl'?>
<dataset>
<name>imglab dataset</name>
<comment>Created by imglab tool.</comment>
<images>
<image file='/home/orcl/user102339/Area123/Geo_Tag_0812-0420.jpg'>
<box top="505" left="326" width="59" height="32">
                <label>SBS_Marks</label>
            </box>
</image>
<image file='/home/orcl/user102339/Area123/Geo_Tag_0812-0544.jpg'>
<box top='343' left='72' width='92' height='29'>
<label>LBS_Marks
</label></box>
<box top="507" left="331" width="50" height="27">
                <label>SBS_Marks</label>
            </box>
</image>
<image file='/home/orcl/user102339/Area123/Geo_Tag_0812-0489.jpg'>
<box top="509" left="330" width="51" height="25">
                <label>SBS_Marks</label>
            </box>

</image>
</images>
</dataset>

在所需的输出示例中,第一图像0420.jpg具有来自第二文件的框和标签元素,第二图像0544.jpg具有来自文件1和文件2的两个框和标签,第三图像具有来自第二文件的框和标签。

我试过使用以下代码:

代码语言:javascript
复制
#!/usr/bin/env python
import sys
from xml.etree import ElementTree

def run(files):
    first = None
    for filename in files:
        data = ElementTree.parse(filename).getroot()
        if first is None:
            first = data
        else:
            first.extend(data)
    if first is not None:
        print ElementTree.tostring(first)

if __name__ == "__main__":
    run(sys.argv[1:])

但是这只是一个接一个地打印文件的内容,但不合并。我不知道如何创建xsl模板,因此无法尝试。有人能帮上一个更好的代码或提供一个xsl模板,以帮助我合并所有这些文件在文件夹中请。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-21 10:06:20

如果您仅限于XSLT 1,那么我认为一种方法是使用Python构造一个XML文档,列出您想要合并的目录中的所有XML文件,例如格式

代码语言:javascript
复制
<files>
  <file name="doc1.xml"/>
  <file name="doc2.xml"/>
  ...
</files>

然后使用该文件作为XSLT的输入文档,并将代码编写为

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <xsl:variable name="files" select="document(files/file/@name)"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/">
        <xsl:apply-templates select="$files[1]/node()"/>
    </xsl:template>

    <xsl:template match="image[@file]">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
            <xsl:apply-templates select="$files[position() > 1]//image[@file = current()/@file]/node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

当然,如果您有数百个文件要合并,那么document(files/file/@name)将把它们全部拖到内存中,但是如果您想将所有文件合并到一个转换中,我看不出有什么办法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47376663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档