XPATH选择其兄弟匹配条件的父级的子级

时间:2015-04-13 16:34:07

标签: xslt xpath

鉴于此XML(从实际内容中简化):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://foo.com">
<name>Project Name</name>
<namespace>
    <name>ROOT</name>
    <namespace>
        <name>A</name>
        <namespace>
            <name>AA</name>
            <subject>
                <name>SUBJECT</name>
            </subject>
            <item>
                <name>ITEM_AA1</name>
            </item>
        </namespace>
    </namespace>
    <namespace>
        <name>B</name>
        <namespace>
            <name>BB</name>
            <subject>
                <name>SUBJECT</name>
            </subject>
            <item>
                <name>ITEM_BB1</name>
            </item>
            <item>
                <name>ITEM_BB2</name>
            </item>
        </namespace>
    </namespace>
</namespace>
</project>

我正在尝试创建一个XSL样式表来转换文本节点,例如ITEM_BB1ITEM_BB2 - 即item/name/text()节点,这些节点是namespace的子子节点具有文字内容name的儿童B元素。

我无法弄清楚如何制作一个正确匹配这些节点的模板。

我尝试使用../和跟随兄弟轴构建表达式,但我没有得到它。这是我的WIP样式表:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="http://foo.com" 
    exclude-result-prefixes="x"
    version="1.0" >

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <xsl:template match="node()|@*">
        <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
    </xsl:template>

    <!-- THIS OPERATES ON THE RIGHT ITEMS AT LEAST, BUT OUT OF CONTEXT -->
    <!--
    <xsl:template match="x:namespace/x:name[text()='B']">
        <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
        <xsl:for-each select="..//x:item/x:name/text()">
            <hello><xsl:value-of select="."/></hello>
        </xsl:for-each>
    </xsl:template>
    -->

    <!-- THIS IS INVALID -->
    <xsl:template match="x:namespace/x:name[text()='B']/..//x:item/x:name/">
        <hello><xsl:value-of select="."/></hello>
    </xsl:template>

</xsl:stylesheet>

我的问题是如何制作模板以匹配这些目标节点?

1 个答案:

答案 0 :(得分:1)

尝试此模板匹配,以避免在模板中使用..表达式

<xsl:template match="x:namespace[x:name/text()='B']//x:item/x:name">

这也可以稍微简化一下......

<xsl:template match="x:namespace[x:name='B']//x:item/x:name">