我们需要制作多个XML文档,每个文档都有一个" info"元素,来自单个XML文档,其中包含未知数量的" info"元素。例如,本文档:
<alert>
<identifier>2.49.0.1.124.76fea972.2015</identifier>
<info>
<language>en</language>
</info>
<info>
<language>fr</language>
</info>
</alert>
应该产生这两个文件:
<alert>
<identifier>2.49.0.1.124.76fea972.2015</identifier>
<info>
<language>en</language>
</info>
</alert>
<alert>
<identifier>2.49.0.1.124.76fea972.2015</identifier>
<info>
<language>fr</language>
</info>
</alert>
修剪一个&#34; info&#34;的兄弟姐妹。我们需要复制所有祖先(到根)的所有节点,属性,命名空间等,以及特定&#34; info&#34;的所有节点,属性,命名空间等。元件。
我是XSLT的新手,不知道如何做到这一点。任何帮助将不胜感激!
答案 0 :(得分:1)
轻松xsh:
my $orig := open file.xml ;
for my $info in /alert/info {
my $clone := clone $orig ;
my $i = count($info/preceding::info) ;
delete $clone/alert/info[count(preceding::info) = $i] ;
save :f concat('file', $i, '.xml') $clone ;
}
答案 1 :(得分:0)
使用像Saxon 9或AltovaXML或XmlPrime这样的XSLT 2.0处理器,你可以使用这样的方法:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="alert/info" mode="split"/>
</xsl:template>
<xsl:template match="info" mode="split">
<xsl:result-document href="language-{language}.xml">
<xsl:apply-templates select="/*">
<xsl:with-param name="info" select="current()" tunnel="yes"/>
</xsl:apply-templates>
</xsl:result-document>
</xsl:template>
<xsl:template match="info">
<xsl:param name="info" tunnel="yes"/>
<xsl:if test=". is $info">
<xsl:next-match/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
如果输入位于某个名称空间中,则使用例如<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xpath-default-namespace="urn:oasis:names:tc:emergency:cap:1.2">
。
如果要独立于命名空间运行XSLT,请使用
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="*:alert/*:info" mode="split"/>
</xsl:template>
<xsl:template match="*:info" mode="split">
<xsl:result-document href="language-{language}.xml">
<xsl:apply-templates select="/*">
<xsl:with-param name="info" select="current()" tunnel="yes"/>
</xsl:apply-templates>
</xsl:result-document>
</xsl:template>
<xsl:template match="*:info">
<xsl:param name="info" tunnel="yes"/>
<xsl:if test=". is $info">
<xsl:next-match/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
或许这比马丁的解决方案简单一点:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<xsl:for-each select="alert/info">
<xsl:result-document href="language-{language}.xml">
<alert>
<xsl:copy-of select="../identifier"/>
<xsl:copy-of select="."/>
</alert>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>