扫描一次或两次xml文件?

时间:2014-03-15 14:17:39

标签: xml xslt

我有一个由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>

问题:我可以一次完成所有这些操作,还是需要两次循环输入文件? (现实情况更复杂,但这是根本问题)。

1 个答案:

答案 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>

变量收集所有 X1X2元素,并将它们存储在变量中。匹配root的模板会修复新结构,并复制X1X2下的E1E2个节点。其他模板会替换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

*