Problem with COPY Apply XSLT Template

I started learning XSLT just recently and came up with a script. The source and target structure are exactly the same as I can execute using the code below:

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

But my requirement is to create a node target only if one of the conditions is met.

Example if

VNum eq 999

source and target should look like this:

A source

  <POExt> <SD>01</SD> <PODet> <PNum schemeAgencyID="TEST">12345678</PNum> <VNum>999</VNum> </PODet> <PODet> <PNum schemeAgencyID="">45654654</PNum> <VNum>001</VNum> </PODet> </POExt> 

goal

  <POExt> <SD>01</SD> <PODet> <PNum schemeAgencyID="TEST">12345678</PNum> <VNum>999</VNum> </PODet> </POExt> 

<PODet> repeated every time it meets the criteria of VNum, if none of the <PODet> meets the criteria in which it is normal,

  <POExt> <SD>01</SD> </POExt> 

Want to accomplish this using Copy and apply-templates, any help would be greatly appreciated.

Thanks..

+4
source share
1 answer

When working with an identification rule, you need to redefine the elements by matching patterns.

In your case, you do not want to copy PODet elements that do not satisfy a certain condition. According to negative logic, you should just "plug" the nodes that do not match your state. For instance:

 <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="PODet[not(VNum/text()=999)]"/> </xsl:stylesheet> 

If your VNum is a variable, say, an input parameter for your conversion, in XSLT 2.0 you can simply:

 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:param name="VNum" select="999"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="PODet[not(VNum/text()=$VNum)]"/> </xsl:stylesheet> 

In XSLT 1.0, variables are not allowed in a template matching template, so you need to enable state checking inside the template. For example, you can only apply templates to elements matching your condition:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:param name="VNum" select="999"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="PODet"> <xsl:apply-templates select="VNum[text()=$VNum]"/> </xsl:template> <xsl:template match="VNum"> <xsl:copy-of select=".."/> </xsl:template> </xsl:stylesheet> 
+3
source

All Articles