我在目录中有100个xml文件。 xml的结构完全相同。但是,我想将xml的一些节点添加到一起并保留其余部分。
示例xml 1
<?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
<?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的框标签。我试图将这些文件合并在一起,这样对于每个图像,我只得到框坐标和标签。例如,所需的输出如下:
<?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,第三个图像具有框和第二个文件中的标签。
我尝试使用此代码:
#!/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模板,帮助我合并文件夹中的所有这些文件。
答案 0 :(得分:1)
如果您仅限于XSLT 1,那么我认为一种方法是使用Python构建一个XML文档,列出您要合并的目录的所有XML文件,例如:格式为
<files>
<file name="doc1.xml"/>
<file name="doc2.xml"/>
...
</files>
然后您将该文件用作XSLT的输入文档并将代码编写为
<?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)
会将它们全部存入内存,但如果您想将它们全部合并到一个转换中,我看不到任何方法。