如何在XSLT中使用apply-template基于另一个兄弟节点的子节点的匹配值来提取兄弟节点的值?

时间:2016-04-08 13:44:17

标签: xml xslt

以下是我的INPUT和OUTPUT XML。如果子节点“language”的值等于使用apply-template的另一个兄弟节点“personalInfo”的“English”,我想提取兄弟节点“ID”的值。

INPUT:   <customers> <customer> <ID>5345245</ID> <personalInfo> <name>John Smith</name> <address>123 Oak St.</address> <state>WA</state> <phone>(206) 123-4567</phone> <language>English</language> </personalInfo> </customer> <customer> <ID>4564545</ID> <personalInfo> <name>Zack Zwyker</name> <address>368 Elm St.</address> <state>WA</state> <phone>(206) 423-4537</phone> <language>English</language> </personalInfo> </customer> <customer> <ID>5653563</ID> <personalInfo> <name>Albert Aikens</name> <address>368 Elm St.</address> <state>WA</state> <phone>(206) 423-4537</phone> <language>spanish</language> </personalInfo> </customer> </customers>

输出:    <customers> <customer> <ID>5345245</ID> </customer> <customer> <ID>4564545</ID> </customer> </customers>

我正在使用下面的代码现在我有上面提到的条件。如果有人能帮忙,我感激不尽。

        <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
    <customers>
    <xsl:copy>
        <xsl:apply-templates select="//*[local-name()='customer']/*[local-name()='ID']"/>
    </xsl:copy>
    </xsl:template>
    <xsl:template match="*[local-name()='ID']">
    <customer>
    <ID>
    <xsl:value-of select="."/>
    </ID>
    </customer>
    </xsl:template>
    </xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

为什么不简单:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/customers">
    <xsl:copy>
        <xsl:for-each select="customer[personalInfo/language='English']">
            <xsl:copy>
                <xsl:copy-of select="ID"/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

与你的问题无关,但你永远不必使用这种黑客:

*[local-name()='customer']

如果您的源使用名称空间,请在样式表中声明它们,为它们分配前缀,并使用分配的前缀来寻址源节点。

加了:

  

使用apply-template是否有其他方法可以实现这一目标?

同样的事情:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/customers">
    <xsl:copy>
        <xsl:apply-templates select="customer[personalInfo/language='English']"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="customer">
    <xsl:copy>
        <xsl:copy-of select="ID"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>