I am in a situation where I can only check for a child node, but I need to apply tags to the grandparent of this child node.
XSLT is not procedural programming, so you need to think about things a little differently.
If I understand correctly, you want to add new tags to your XML (additional child elements or attributes?), But you want to add them to the ancestor when you find a specific descendant. Your sample code is trying to target grandfather when you encounter a child. Unfortunately, this may be too late.
You may need to introduce a new element / attribute when the engine encounters the element you want to change (grandfather in your case), and not when it meets a child that meets the condition (or you will end up adding elements or attributes to the child)
Consider this entry (grandparent = "album", grandchild = "label"):
<?xml version="1.0" encoding="UTF-8"?> <album> <title>Sgt. Pepper Lonely Hearts Club Band</title> <artist>The Beatles</artist> <year>1967</year> <labels> <label>Parlophone</label> <label>Capitol</label> </labels> </album>
I want to change the album based on the presence of a specific label . Remember that the general format for targeting nodes is: target-node[target-condition] . To change any album elements that have a Capitol label poem element, I would use the following:
album[*/label='Capitol']
Therefore, consider this stylesheet to add a new attribute and 2 new children to the album that match my condition:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="album[*/label='Capitol']"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:attribute name="new-attribute">A Capitol Record</xsl:attribute> <new-element1/> <xsl:apply-templates select="node()"/> <new-element2/> </xsl:copy> </xsl:template> </xsl:stylesheet>
Output (manually formatted):
<?xml version="1.0" encoding="UTF-8"?> <album new-attribute="A Capitol Record"> <new-element1/> <title>Sgt. Pepper Lonely Hearts Club Band</title> <artist>The Beatles</artist> <year>1967</year> <labels> <label>Parlophone</label> <label>Capitol</label> </labels> <new-element2/> </album>
Some resources of the test environment:
Bert f
source share