Add attribute to XML tag based on different tag value

I'm trying to wrap my head around xslt ... trying to convert the following xml:

<employees> <employee> <employeeNumber>1234</employeeNumber> <startdate>01/02/2003</startdate> <activeFlag>true</activeFlag> <firstname>Erik</firstname> <address> <addressline1>123 Main</addressline1> <zip>07016</zip> <state>New Jersey</state> <city>My City</city> </address> </employee> </employees> 

into this (i.e. print the value of the activeFlag tag and put it in the attribute of the employee tag).

 <employees> <employee active="true"> <employeeNumber>1234</employeeNumber> <startdate>01/02/2003</startdate> <firstname>Erik</firstname> <address> <addressline1>123 Main</addressline1> <zip>07016</zip> <state>New Jersey</state> <city>My City</city> </address> </employee> </employees> 

I tried the following XSLT, but it just does nothing:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="employees/employee"> <employee active="{activeFlag}"/> </xsl:template> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> 

Any ideas?

+4
source share
2 answers

This is a short and simple (without explicit conditional instructions) conversion :

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="employee"> <employee active="{activeFlag}"> <xsl:apply-templates select="node()|@*"/> </employee> </xsl:template> <xsl:template match="activeFlag"/> </xsl:stylesheet> 

when applied to the provided XML document :

 <employees> <employee> <employeeNumber>1234</employeeNumber> <startdate>01/02/2003</startdate> <activeFlag>true</activeFlag> <firstname>Erik</firstname> <address> <addressline1>123 Main</addressline1> <zip>07016</zip> <state>New Jersey</state> <city>My City</city> </address> </employee> </employees> 

creates the desired, correct result :

 <employees> <employee active="true"> <employeeNumber>1234</employeeNumber> <startdate>01/02/2003</startdate> <firstname>Erik</firstname> <address> <addressline1>123 Main</addressline1> <zip>07016</zip> <state>New Jersey</state> <city>My City</city> </address> </employee> </employees> 

Explanation : rule override using AVT .

If you want to handle cases where the activeFlag child does not exist activeFlag , it becomes a little more complicated :

  <xsl:template match="employee"> <employee active= "{concat(activeFlag, substring('false', 1 div not(activeFlag)) ) }"> <xsl:apply-templates select="node()|@*"/> </employee> </xsl:template> 
+3
source

This XSLT 1.0 style sheet:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="employee"> <xsl:copy> <xsl:if test="activeFlag"> <xsl:attribute name="active"><xsl:value-of select="activeFlag"/></xsl:attribute> </xsl:if> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="activeFlag"/> </xsl:stylesheet> 

the XML applied to your example creates:

 <employees> <employee active="true"> <employeeNumber>1234</employeeNumber> <startdate>01/02/2003</startdate> <firstname>Erik</firstname> <address> <addressline1>123 Main</addressline1> <zip>07016</zip> <state>New Jersey</state> <city>My City</city> </address> </employee> </employees> 

You can remove xsl:if if you are sure that activeFlag will exist, or if you do not care if the attribute is created regardless of whether it exists or not.

Also, the reason your stylesheet doesn't work is because you didn't apply templates in your employees/employee match. You can also use this template:

  <xsl:template match="employees/employee"> <employee active="{activeFlag}"> <xsl:apply-templates/> </employee> </xsl:template> 
+3
source

Source: https://habr.com/ru/post/1396237/


All Articles