使用shell脚本合并多个xml文件

时间:2017-07-23 09:20:06

标签: xml shell xslt

我想合并多个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

但是,脚本只执行一次合并

谢谢你的帮助

2 个答案:

答案 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-collectiontransform以及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