在xslt中合并xml文件时

问题描述

我正在尝试使用xslt和saxon-HE 9.9.1 .NET合并特定文件夹中的多个xml文件。我需要创建一个通用合并,这样我就不会在模板内添加静态标签以将其与不同节点的名称一起使用,我尝试制作一个循环以在开始时一次添加根或顶级标签,但同时在xml结束之前关闭标签,但顶层标签有问题 例: XML File1:

<Arr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <Src>
    <name>C</name>
    <pr>pr</pr>
    <par>
      <Q>
        <isC>false</isC>
        <name>hrh1</name>
        <type>xx1</typ>
      </Q>
    </par>
    <st />
 </Src>
 <Src>
    <name>C</name>
    <pr></pr>
    <par>
      <Q>
        <isC>false</isC>
        <name>hrh2</name>
        <type>xx2</typ>
      </Q>
    </par>
    <st>
      <Src>
        <name>st1</name>
        <pr>prst1</pr>
        <par>
          <Q>
            <isC>false</isC>
            <name>q1</name>
            <type>t1</type>
          </Q>
          <Q>
            <isC>false</isC>
            <name>q2</name>
            <type>t2</type>
          </Q>
        </par>
        <st />
      </Src>
    </st>
  </Src>
 </Arr>

XML File2:

<Arr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <Src>
    <name>CFile2</name>
    <pr>C2</pr>
    <par>
      <Q>
        <isC>false</isC>
        <name>hrh1</name>
        <type>xx1</typ>
      </Q>
    </par>
    <st />
 </Src>
 </Arr>

预期输出

<Arr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <Src>
    <name>C</name>
    <pr>pr</pr>
    <par>
      <Q>
        <isC>false</isC>
        <name>hrh1</name>
        <type>xx1</typ>
      </Q>
    </par>
    <st />
 </Src>
 <Src>
    <name>C</name>
    <pr></pr>
    <par>
      <Q>
        <isC>false</isC>
        <name>hrh2</name>
        <type>xx2</typ>
      </Q>
    </par>
    <st>
      <Src>
        <name>st1</name>
        <pr>prst1</pr>
        <par>
          <Q>
            <isC>false</isC>
            <name>q1</name>
            <type>t1</type>
          </Q>
          <Q>
            <isC>false</isC>
            <name>q2</name>
            <type>t2</type>
          </Q>
        </par>
        <st />
      </Src>
    </st>
  </Src>
  <Src>
    <name>CFile2</name>
    <pr>C2</pr>
    <par>
      <Q>
        <isC>false</isC>
        <name>hrh1</name>
        <type>xx1</typ>
      </Q>
    </par>
    <st />
  </Src>
 </Arr>

我当前的模板由于顶层标签关闭而产生错误输出

<?xml version="1.0" encoding="windows-1256"?>   
<xsl:stylesheet version="3.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:user="http://tempuri.org/msxsl" >     
 <xsl:output method="xml" indent="yes" encoding="windows-1256" />

<xsl:template name="main">
 
 <xsl:for-each select="collection('.?select=*.xml')/*">
  <xsl:choose>
        <xsl:when test="position() = 1">
          <xsl:copy>
        <xsl:copy-of select="/*/node()"/> 
        </xsl:copy>
   
        </xsl:when>
        <xsl:otherwise>
         <xsl:copy-of select="/*/node()"/> 
        </xsl:otherwise>
      </xsl:choose>
      
</xsl:for-each> 

</xsl:template>

</xsl:stylesheet>

我使用以下命令从cmd运行:

transform -it:main -xsl:merge_xml.xslt -o:output.xml

我当前的输出错误

<Arr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <Src>
    <name>C</name>
    <pr>pr</pr>
    <par>
      <Q>
        <isC>false</isC>
        <name>hrh1</name>
        <type>xx1</typ>
      </Q>
    </par>
    <st />
 </Src>
 <Src>
    <name>C</name>
    <pr></pr>
    <par>
      <Q>
        <isC>false</isC>
        <name>hrh2</name>
        <type>xx2</typ>
      </Q>
    </par>
    <st>
      <Src>
        <name>st1</name>
        <pr>prst1</pr>
        <par>
          <Q>
            <isC>false</isC>
            <name>q1</name>
            <type>t1</type>
          </Q>
          <Q>
            <isC>false</isC>
            <name>q2</name>
            <type>t2</type>
          </Q>
        </par>
        <st />
      </Src>
    </st>
  </Src>
</Arr>
  <Src>
    <name>CFile2</name>
    <pr>C2</pr>
    <par>
      <Q>
        <isC>false</isC>
        <name>hrh1</name>
        <type>xx1</typ>
      </Q>
    </par>
    <st />
  </Src>

解决方法

我会简单地使用

 <xsl:param name="uris" select="uri-collection('.?select=*.xml')"/>

 <xsl:template name="xsl:initial-template">
    <xsl:copy select="$uris => head() => doc()/*">
      <xsl:copy-of select="($uris ! doc(.))/*/node()"/>
    </xsl:copy>
  </xsl:template>

如果可以尝试使用Saxon EE,则可以切换到流式传输

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all" expand-text="yes">

    <xsl:function name="mf:merge" as="document-node()">
        <xsl:param name="uris"/>
        <xsl:source-document href="{head($uris)}" streamable="yes">
            <xsl:document>
                <xsl:copy select="*">
                    <xsl:copy-of select="node()"/>
                    <xsl:iterate select="tail($uris)">
                        <xsl:source-document href="{.}" streamable="yes">
                            <xsl:copy-of select="*/node()"/>
                        </xsl:source-document>
                    </xsl:iterate>
                </xsl:copy>
            </xsl:document>
        </xsl:source-document>
    </xsl:function>

    <xsl:output method="xml" indent="yes"/>

    <xsl:template name="xsl:initial-template">
        <xsl:sequence select="mf:merge(uri-collection('?select=*.xml'))"/>
    </xsl:template>

</xsl:stylesheet>
,

马丁的解决方案可以工作,但我可以:

  <xsl:template name="xsl:initial-template">
    <xsl:variable name="coll" select="collection('.?select=*.xml')"/>
    <xsl:copy select="$coll[1]/*">
      <xsl:copy-of select="$coll/*/*"/>
    </xsl:copy>
  </xsl:template>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...