Reputation: 16265
Given this XML (simplified from the real content):
<?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>
I am trying to create an XSL stylesheet to transform text nodes such as ITEM_BB1
and ITEM_BB2
- i.e. item/name/text()
nodes which are sub-children of the namespace
with a child name
element which has the text content B
.
I am having trouble figuring out how to make a template which correctly matches those nodes.
I have tried building an expression with ../
and with following-sibling axis, but am not getting it. Here is my WIP stylesheet:
<?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>
My question is how to make a template to match those target nodes?
Upvotes: 1
Views: 897
Reputation: 70648
Try this template match, to avoid using the ..
expression in the template
<xsl:template match="x:namespace[x:name/text()='B']//x:item/x:name">
This can be slightly simplified to this too...
<xsl:template match="x:namespace[x:name='B']//x:item/x:name">
Upvotes: 1