我想合并多个xml文件。我发现一个很好的命令可以完美地合并两个xml文件Merge Command。所以要合并多个文件,将命令放入shell脚本。
脚本如下:
#!/bin/bash
for i in `ls recep` //recep is the directory containing the list of xmlfiles
do
saxon tt merge.xslt with=$i > aux //tt is a file, we create it and initiate
it to the first xml file
cp aux tt
done
cat tt
但是,脚本只执行一次合并
谢谢你的帮助
答案 0 :(得分:1)
我创建了一个简单的测试用例来检查你的脚本。所以我下载了提到的merge.xslt
文件并创建了一些文件。
总体而言,测试用例如下所示:
<强> TT:强>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<List>
<Field0>Value X</Field0>
</List>
</root>
名为recep
的子目录中的 a1.xml - a4.xml ,FieldX
值等于XML文件号:
<root>
<List>
<Field1>Value X</Field1>
</List>
</root>
然后我稍微修改了你的脚本以匹配我的撒克逊安装:
#!/bin/bash
for i in `ls recep`
do
java -jar /pathToSaxon/saxon9he.jar --suppressXsltNamespaceCheck tt merge.xslt with=recep/$i > aux
cp aux tt
done
cat tt
执行脚本 tt 包含:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<List>
<Field0>Value X</Field0>
<Field1>Value X</Field1>
<Field2>Value X</Field2>
<Field3>Value X</Field3>
<Field4>Value X</Field4>
</List>
</root>
所以最终的结果是:
我无法重现你的错误。它必须是缺少目录名称(ls recep/*
)左右的东西,因为merge.xslt
确实按预期工作。
答案 1 :(得分:0)
作为替代方案,在XSLT 3.0中,还可以使用https://www.w3.org/TR/xpath-functions-31/中的uri-collection
和transform
以及fold-left
来对文件集合执行合并样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs math mf"
version="3.0">
<xsl:param name="input-dir" as="xs:string?" select="'.'"/>
<xsl:param name="file-selection-pattern" as="xs:string" select="'?select=*.xml'"/>
<!-- saved merge.xslt from http://web.archive.org/web/20160809092524/http://www2.informatik.hu-berlin.de/~obecker/XSLT/#merge as original-merge.xslt -->
<xsl:param name="merge-code-uri" as="xs:string" select="'original-merge.xslt'"/>
<xsl:param name="merge-sheet" as="document-node()" select="doc($merge-code-uri)"/>
<!--
Call Saxon 9.8 with option -it to start with below template that allows merging a collection of files
as specified by the parameters $input-dir and $file-selection-pattern.
-->
<xsl:template name="xsl:initial-template">
<xsl:variable name="input-uris" as="xs:anyURI*" select="uri-collection($input-dir || $file-selection-pattern)"/>
<xsl:sequence select="mf:merge($input-uris)"/>
</xsl:template>
<xsl:function name="mf:merge" as="node()*">
<xsl:param name="input-uris" as="xs:anyURI*"/>
<xsl:sequence select="fold-left(tail($input-uris), doc(head($input-uris)), mf:merge#2)"/>
</xsl:function>
<xsl:function name="mf:merge" as="node()*">
<xsl:param name="doc1" as="document-node()"/>
<xsl:param name="doc2-uri" as="xs:string"/>
<xsl:sequence select="transform(map {
'stylesheet-node' : $merge-sheet,
'source-node' : $doc1,
'stylesheet-params' : map { xs:QName('with') : $doc2-uri }
})?output"/>
</xsl:function>
</xsl:stylesheet>
更详细的解释在http://xslt-3-by-example.blogspot.de/2017/07/functional-programming-with-fold-left.html。