XSLT: how to copy parent nodes unchanged and convert child nodes

I am new to XSLT, so this is probably very simple, but I would really appreciate input. I need to convert child nodes in my xml, but at the same time keep the parent nodes intact. My xml looks like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <XMLTest xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xmlns:jfxpf="http://www.xfa.com/schema/xml-package" xmlns:xfa="http://www.xfa.com/schema/xfa-data"> <result form="10" version="4" resultid="23146" respondent="ycisxmir" authid="" date="2012-09-12 06:39:44" times="462"> <Q0061 answerid="1">1</Q0061> <Q0060 answerid="2">2</Q0060> <QTXT1>1</QTXT1> </result> </XMLTest> 

I need to save the top two XMLTest nodes and the result will not change, while the child nodes must be converted to a more general format:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <XMLTest xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xmlns:jfxpf="http://www.xfa.com/schema/xml-package" xmlns:xfa="http://www.xfa.com/schema/xfa-data"> <result form="10" version="4" resultid="23146" respondent="ycisxmir" authid="" date="2012-09-12 06:39:44" times="462"> <answer>Q0061</answer> <id>1</id> <value>1</value> <answer>Q0060</answer> <id>2</id> <value>2</value> <answer>QTXT1</answer> <value>1</value> </result> </XMLTest> 

My xslt looks like this:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:template match="result/*"> <answer><xsl:value-of select="local-name()"/></answer> <id><xsl:value-of select="@answerid"/></id> <value><xsl:value-of select="@*"/></value> </xsl:template> </xsl:stylesheet> 

I tried using xsl: copy on the top nodes, but can't make it work without losing child nodes, or converting child nodes. How can I hold the top nodes and force them through the converted child nodes at the same time?

+4
source share
2 answers

Start with

 <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> 

Now add templates for necessary transformations i.e.

 <xsl:template match="result/*[@answerid]"> <answer><xsl:value-of select="local-name()"/></answer> <id><xsl:value-of select="@answerid"/></id> <value><xsl:value-of select="."/></value> </xsl:template> <xsl:template match="result/*[not(@answerid)]"> <answer><xsl:value-of select="local-name()"/></answer> <value><xsl:value-of select="."/></value> </xsl:template> 
+2
source

You are missing an identification template:

 <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> 

I fixed that you answer ..:

 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:template match="/XMLTest/result/*"> <answer> <xsl:value-of select="local-name()"/> </answer> <id> <xsl:value-of select="@answerid"/> </id> <value> <xsl:value-of select="@*"/> </value> </xsl:template> </xsl:stylesheet> 

Edit1: the updated template to cancel if the attributes are null: the if condition checks if the attribute is null before converting it to an element.

  <xsl:template match="/XMLTest/result/*"> <answer> <xsl:value-of select="local-name()"/> </answer> <xsl:if test="@answerid/.!=''"> <id> <xsl:value-of select="@answerid"/> </id> </xsl:if> <xsl:if test="@*/.!=''"> <value> <xsl:value-of select="@*"/> </value> </xsl:if> </xsl:template> 

Edit2: in your early ur attempts, you tried to copy the @ * value, @* indicates the anyname attribute, so he copied the @answerid value (since that was the only attribute available) .. what you had to do .. valu-of="." .. try the code below ..

  <xsl:template match="/XMLTest/result/*"> <answer> <xsl:value-of select="local-name()"/> </answer> <xsl:if test="@answerid/.!=''"> <id> <xsl:value-of select="@answerid"/> </id> </xsl:if> <xsl:if test=".!=''"> <value> <xsl:value-of select="."/> </value> </xsl:if> </xsl:template> 
+1
source

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


All Articles