XSLT Changing A Node Via A Named Template Call From Within A Different Node
Edit: the error was in a wrong when
condition.
Source xml:
<?xml version="1.0" encoding="UTF-8"?>
<mainNode>
<levelOneNodes>
<levelOneNode>
<value name="triggeringValue">
<levelTwoNodes>
<levelTwoNode attributeOne="A" attributeTwo="A" attributeThree="A">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode attributeOne="B1" attributeTwo="B1" attributeThree="B1">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode attributeOne="C1" attributeTwo="C1" attributeThree="C1">
<textData>This is some text.</textData>
</levelTwoNode>
</levelTwoNodes>
</value>
</levelOneNode>
<levelOneNode>
<value name="anotherValue">
<levelTwoNodes>
<levelTwoNode attributeOne="A" attributeTwo="A" attributeThree="A">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode attributeOne="B2" attributeTwo="B2" attributeThree="B2">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode attributeOne="C2" attributeTwo="C2" attributeThree="C2">
<textData>This is some text.</textData>
</levelTwoNode>
</levelTwoNodes>
</value>
</levelOneNode>
</levelOneNodes>
</mainNode>
Expected trasnformed xml:
<?xml version="1.0" encoding="UTF-8"?>
<mainNode>
<levelOneNodes>
<levelOneNode>
<value name="triggeringValue">
<levelTwoNodes>
<levelTwoNode injectedAttribute="triggeringValue" attributeOne="A" attributeTwo="A" attributeThree="A">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode injectedAttribute="triggeringValue" attributeOne="B1" attributeTwo="B1" attributeThree="B1">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode injectedAttribute="triggeringValue" attributeOne="C1" attributeTwo="C1" attributeThree="C1">
<textData>This is some text.</textData>
</levelTwoNode>
</levelTwoNodes>
</value>
</levelOneNode>
<levelOneNode>
<value name="anotherValue">
<levelTwoNodes>
<levelTwoNode injectedAttribute="triggeringValue" attributeOne="A" attributeTwo="A" attributeThree="A">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode attributeOne="B2" attributeTwo="B2" attributeThree="B2">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode attributeOne="C2" attributeTwo="C2" attributeThree="C2">
<textData>This is some text.</textData>
</levelTwoNode>
</levelTwoNodes>
</value>
</levelOneNode>
</levelOneNodes>
</mainNode>
That is, when a levelTwoNode node nested into a value node with attribute name "triggeringValue" is encountered, all the levelTwoNode nodes in the document with the same attributeOne and attributeTwo as the triggering node's should be injected with the attribute injectedAttribute="triggeringValue".
I am using this xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output encoding="Windows-1252" method="xml" indent="no" omit-xml-declaration="no" />
<!-- Copy the whole output -->
<xsl:template match="@* |node() ">
<xsl:copy>
<xsl:apply-templates select="@* |node() "/>
</xsl:copy>
</xsl:template>
<xsl:template match="//levelOneNodes/levelOneNode/value/levelTwoNodes/levelTwoNode" >
<xsl:call-template name="myTemplate">
<xsl:with-param name="myAttrOne" select=" current()/@attributeOne " />
<xsl:with-param name="myAttrTwo" select=" current()/@attributeTwo " />
<xsl:with-param name="myValue" select=" current()/../../@name " />
</xsl:call-template>
</xsl:template>
<xsl:template name="myTemplate">
<xsl:param name="myAttrOne" />
<xsl:param name="myAttrTwo" />
<xsl:param name="myValue" />
<xsl:choose>
<xsl:when test="boolean(//levelTwoNode[(@attributeOne = $myAttrOne) and (@attributeTwo = $myAttrTwo)]) and boolean($myValue = 'triggeringValue')">
<xsl:copy>
<xsl:attribute name="injectedAttribute"><xsl:value-of select="$myValue"/></xsl:attribute>
<xsl:apply-templates select="@* |node() "/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@* |node() "/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
that results in this xml:
<?xml version="1.0" encoding="Windows-1252"?><mainNode>
<levelOneNodes>
<levelOneNode>
<value name="triggeringValue">
<levelTwoNodes>
<levelTwoNode injectedAttribute="triggeringValue" attributeOne="A" attributeTwo="A" attributeThree="A">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode injectedAttribute="triggeringValue" attributeOne="B1" attributeTwo="B1" attributeThree="B1">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode injectedAttribute="triggeringValue" attributeOne="C1" attributeTwo="C1" attributeThree="C1">
<textData>This is some text.</textData>
</levelTwoNode>
</levelTwoNodes>
</value>
</levelOneNode>
<levelOneNode>
<value name="anotherValue">
<levelTwoNodes>
<levelTwoNode attributeOne="A" attributeTwo="A" attributeThree="A">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode attributeOne="B2" attributeTwo="B2" attributeThree="B2">
<textData>This is some text.</textData>
</levelTwoNode>
<levelTwoNode attributeOne="C2" attributeTwo="C2" attributeThree="C2">
<textData>This is some text.</textData>
</levelTwoNode>
</levelTwoNodes>
</value>
</levelOneNode>
</levelOneNodes>
</mainNode>
where the new attribute injectedAttribute is not injected into the first levelTwoNode of the second levelOneNode (the one with the child node value with attribute name "anotherValue") even though it has the same attributeOne and attributeTwo (with value "A") of one of the levelTwoNode nodes inside the first levelOneNode node (the one with the child node value with attribute name "triggeringValue"). The attribute injectedAttribute is injected only in all the levelTwoNode nodes inside the triggeringValuevalue node.
Why does this condition:
<xsl:when test="boolean(//levelTwoNode[(@attributeOne = $myAttrOne) and (@attributeTwo = $myAttrTwo)]) and boolean($myValue = 'triggeringValue')">
is limited in the scope of the calling node? The query //levelTwoNode[(@attributeOne = $myAttrOne) and (@attributeTwo = $myAttrTwo)]
should fetch all levelTwoNode nodes with the passed attributes and the condition $myValue = 'triggeringValue'
should not limit that query.
What am I missing?
Thanks for any help.
Answer
You say "the condition $myValue = 'triggeringValue' should not limit that query" but it should. The variable $myValue is bound to current()/../../@name
and I think you will find its value is "anotherValue".
Related Questions
- → CORS missmatch because of http
- → French Characters from MySQL database to PHP with XML eport fail
- → How do I get JUnit XML output from Jest?
- → Wordpress Sitemap XML Error while using with Custom Permalinks
- → XMLHttpRequest cannot load file:///C:/
- → How to add rich snippet in a website?
- → Your Sitemap does not contain any URLs. Please validate and resubmit your Sitemap?
- → Multi level html drop-down from XML
- → I have sitemap.xml but many SEO audit websites say I don't have...what is the fix?
- → Shopify Updating Inventory 400 Bad Request
- → Update order with basket xml
- → Is it valid to add categories to sitemap.xml?
- → Sitemap Generator detect Only Home Page and also screaming frog detects only homepage