拆分重新创建XML XSLT

时间:2014-10-31 16:44:58

标签: xml xslt split copy

我想将xml拆分为多个xml,但是所有拆分的xml中都必须存在一些常见元素。

输入

<xmlroot>
<FileDetails>
   <Filename>test.xml</FileName>
   <FileDate>10312014</FileDate>
</FileDetails>
 <FileInfo>
   <Test>Hello1</Test>
 </FileInfo>
 <FileInfo>
    <Test>Hello2</Test>
 </FileInfo>
 </xmlroot>

输出1

<xmlroot>
<FileDetails>
   <Filename>test.xml</FileName>
   <FileDate>10312014</FileDate>
</FileDetails>
 <FileInfo>
    <Test>Hello1</Test>
 </FileInfo>
</xmlroot>

OUTPUT2

<xmlroot>
<FileDetails>
   <Filename>test.xml</FileName>
   <FileDate>10312014</FileDate>
</FileDetails>
 <FileInfo>
    <Test>Hello2</Test>
 </FileInfo>
 </xmlroot>

1 个答案:

答案 0 :(得分:0)

假设XSLT 2.0

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="/">
  <xsl:apply-templates select="*/FileInfo"/>
</xsl:template>

<xsl:template match="*/FileInfo">
  <xsl:result-document href="Output{position()}.xml">
    <xsl:apply-templates select="/*" mode="split">
      <xsl:with-param name="target" tunnel="yes" select="current()"/>
    </xsl:apply-templates>
  </xsl:result-document>
</xsl:template>

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

<xsl:template match="*/FileInfo" mode="split">
  <xsl:param name="target" tunnel="yes"/>
  <xsl:if test="$target is .">
    <xsl:next-match/>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

如果你需要在XSLT 1.0中使用Xalan Java的解决方案,但是使用Xalan特定的扩展元素,那么这是一个例子:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:redirect="http://xml.apache.org/xalan/redirect"
  extension-element-prefixes="redirect"
  exclude-result-prefixes="redirect"
  version="1.0">

<xsl:output indent="yes"/>

<xsl:template match="/">
  <xsl:apply-templates select="*/FileInfo" mode="split"/>
</xsl:template>

<xsl:template match="*/FileInfo" mode="split">
  <redirect:write file="OutputXalanTest{position()}.xml">
    <xsl:apply-templates select="/*">
      <xsl:with-param name="target" select="current()"/>
    </xsl:apply-templates>
  </redirect:write>
</xsl:template>

<xsl:template match="@* | node()" name="identity">
  <xsl:param name="target"/>
  <xsl:copy>
    <xsl:apply-templates select="@* | node()">
      <xsl:with-param name="target" select="$target"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="*/FileInfo">
  <xsl:param name="target"/>
  <xsl:if test="generate-id($target) = generate-id(.)">
    <xsl:call-template name="identity"/>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

我只测试了Apache提供的Xalan版本,但希望它与Java JRE中包含的Xalan版本Sun / Oracle一样好。