我有一个由XSLT转换的XML文件。它有两种标签,比如X1和X2标签,随机放置在XML文件中。我需要元素E1中的X1处理的结果,然后,在该元素E1之后,第二个元素E2具有X2标签的处理结果。 所以XML文件看起来像:
<root>
...
<X1/>
...
<X2/>
...
<X1/>
...
<X1/>
...
<X2/>
...
etc.
</root>
和结果文件:
<root1>
<E1>
<x1/>
<x1/>
<x1/>
</E1>
<E2>
<x2/>
<x2/>
</E2>
</root1>
问题:我可以一次完成所有这些操作,还是需要两次循环输入文件? (现实情况更复杂,但这是根本问题)。
答案 0 :(得分:3)
对于您使用输入数据发布的示例,此样式表将为您提供所需的结果。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" />
<xsl:variable name="x1" select="//X1"/>
<xsl:variable name="x2" select="//X2"/>
<xsl:template match="root">
<root1>
<E1>
<xsl:apply-templates select="$x1"/>
</E1>
<E2>
<xsl:apply-templates select="$x2"/>
</E2>
</root1>
</xsl:template>
<xsl:template match="X1">
<x1><xsl:apply-templates/></x1>
</xsl:template>
<xsl:template match="X2">
<x2><xsl:apply-templates/></x2>
</xsl:template>
</xsl:stylesheet>
变量收集所有 X1
和X2
元素,并将它们存储在变量中。匹配root
的模板会修复新结构,并复制X1
和X2
下的E1
和E2
个节点。其他模板会替换X1
/ X2
的{{1}} / x1
。
如果它们不必是小写的,您可以使用x2
:
<xsl:copy>
或者,在XSLT 2.0中:
<xsl:template match="X2|X1">
<xsl:copy><xsl:apply-templates/></xsl:copy>
</xsl:template>
在XSLT 1.0中,您需要将其用于小写
<xsl:template match="X2|X1">
<xsl:element name="{lower-case(name())}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
实际上,由于translate(name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')
模板准确选择了您感兴趣的节点,因此您无需在每个模板中再次执行该操作,并且可以使用root
:
*