XSL:for-each或templates更好地解决了这个Source XML?

时间:2011-11-10 17:13:34

标签: xslt

源XML:

<A>
    <B>
        <Yes>Y</Yes>
        <Address>
            <Type>Present</Type>
            <DoorNo>354</DoorNo>
            <Line>ABCD</Line>
        </Address>
        <Address>
            <Type>Permanent</Type>
            <DoorNo>354</DoorNo>
            <Line>ABCD</Line>
        </Address>
    </B>
    <B>
        <Yes>N</Yes>
        <Address>
            <Type>Present</Type>
            <DoorNo>354</DoorNo>
            <Line>ABCD</Line>
        </Address>
        <Address>
            <Type>Permanent</Type>
            <DoorNo>354</DoorNo>
            <Line>ABCD</Line>
        </Address>
    </B>
    <D>
        <Address>
            <Type>Office</Type>
            <DoorNo>354</DoorNo>
            <Line>ABCD</Line>
        </Address>
    </D>
</A>

我的代码使用for-each:

<Address> 
<xsl:for-each select="A/B[Yes = 'Y']">
    <xsl:for-each select="Address">
        <xsl:if test="DoorNo = ../../D/Address/DoorNo">
            <xsl:value-of select="Line"/>
        </xsl:if>
    </xsl:for-each>
</xsl:for-each>
</Address>

输出应该是:

<Address>
    ABCD
</Address>

与我的If条件一样,当A / B /地址的DoorNo等于A / D /地址的DoorNo时,标签值应为A / B的'Y',则输出必须如下:

如果Present和Permanent地址相同,则只应在输出中显示其中一个地址。    否则必须满足IF条件。

从两天开始,我试图用带有Count变量的递归模板替换每个 - 但是我无法获得一个地址。

我正在尝试使用递归模板,如下所示。    如果具有相同DoorNo值的地址大于'1'则计数&lt; = 1应该起作用,并且只有第一地址的行必须显示。必须避免使用倍数地址值。

先谢谢那些为此尝试解决方案的人 非常感谢那些解决它的人。

2 个答案:

答案 0 :(得分:1)

很难确定你要做的是什么。这是你想要的吗?这将为[Yes = 'Y']

的每个B元素输出一个地址行
<Address> 
<xsl:for-each select="A/B[Yes = 'Y']">
    <xsl:for-each select="Address[DoorNo = ../../D/Address/DoorNo][1]">
        <xsl:value-of select="Line"/>
    </xsl:for-each>
</xsl:for-each>
</Address>

答案 1 :(得分:1)

您问题的标题似乎与您描述的问题无关。

使用XSLT模板规则的好处不是来自更好地处理一个特定源文档的能力,它来自于所得到的代码在一系列不同源文档中的可重用性,这些源文档彼此不同,或者更大或者更高。程度较轻。所以你题目中的问题是错误的问题;要知道为使样式表具有通用性和可重用性需要付出多少努力,我们需要了解它现在或将来必须处理的文档类,而不仅仅是一个特定的示例输入。