xml - 使用 xsl 将单个 XML 文档转换为多个文档

标签 xml xslt transform

给定以下 xml 文档:

<XML>
<doc1>
</doc1>
<doc2>
</doc2>
<XML>

我希望使用 xsl 转换来生成 2 个 XML 文档:

<XML>
<doc1>
</doc1>
<XML>

还有

<XML>
</doc2>
<doc2>
<XML>

这可能吗?

最佳答案

在 XSLT 1.0 中,不可能创建多于一棵树作为任何转换的输出,但在 XSLT 2.0 中这可以非常容易地完成。

在 XSLT 1.0 中,可以使用 <exsl:document> EXSLT 的扩展元素。

或者,可以进行一个转换,即提供一个全局(且外部指定的)参数,其中包含必须提取到单个文档中的元素的元素名称:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pDocElement" select="'doc1'"/>

 <xsl:template match="/*/*">
  <xsl:if test="name()=$pDocElement">
   <xsl:apply-templates select="." mode="copy"/>
  </xsl:if>
 </xsl:template>

 <xsl:template match="node()" mode="copy">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="text()"/>
</xsl:stylesheet>

应用于此 XML 文档时(基于提供的文档):

<t>
    <doc1>
  Doc 1 Content
    </doc1>
    <doc2>
  Doc 2 Content
    </doc2>
    <doc3>
  Doc 3 Content
    </doc3>
</t>

产生了想要的结果:

<doc1>
  Doc 1 Content
</doc1>

您将为每个元素运行一次此转换,其子树应提取到单独的文档中


这是一个 XSLT 2.0 解决方案:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="/*/*[starts-with(name(),'doc')]">
  <xsl:result-document href="{name()}.xml">
   <xsl:apply-templates select="." mode="copy"/>
  </xsl:result-document>
 </xsl:template>

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

当此转换应用于以下 XML 文档时(基于提供的文档):

<t>
    <doc1>
  Doc 1 Content
    </doc1>
    <doc2>
  Doc 2 Content
    </doc2>
    <doc3>
  Doc 3 Content
    </doc3>
</t>

结果正确输出到三个文档:

Saxon 9.1.0.5J from Saxonica
Java version 1.6.0_21
Stylesheet compilation time: 868 milliseconds
Loading net.sf.saxon.event.MessageEmitter
Writing to file:/C:/Program%20Files/Java/jre6/bin/doc1.xml
Writing to file:/C:/Program%20Files/Java/jre6/bin/doc2.xml
Writing to file:/C:/Program%20Files/Java/jre6/bin/doc3.xml
Execution time: 151 milliseconds
Memory used: 11467936
NamePool contents: 18 entries in 18 chains. 6 prefixes, 6 URIs

关于xml - 使用 xsl 将单个 XML 文档转换为多个文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3696083/

相关文章:

xslt - 如何遍历前面的 sibling 直到某个点

javascript - 如何获取#perspective div 的样式转换 perspective-origin 属性

php - 使用 xml 将 javascript 变量发布到服务器

xml - 在go中用xml节点名序列化int

xml - XSLT 元素的逗号分隔

actionscript-3 - 从长方形变成梯形

algorithm - 使用像 Photoshop 这样的 RaphaelJs 在角落旋转元素

c# - Linq 2 XML 不返回基于属性值的元素

不带架构的 sharepoint 数据 View Web 部件 xslt

java - XML:处理大数据