1

How can I transform the xml in format1 to a string as mentioned in format2 using XSLT?

format 1

 <children>
    <child data="test1">
    <content><name>test1</name>
     <child>
      <content><name>test1child</name>
     </child>
    </child>
    </children>

format 2

"<root>"
+"<item id='test1'>"
+"<content><name>test1</name></content>"
+"<item parent_id='test1'>"             
+"<content><name>test1child</name>"
+"</content>"      
+"</item>"
+</item>
+"<root>"

so children should replace with root, child should replaced with item and child of child should be replaced with *item parent_id of parent id*. Is it possible to do with xslt?

2
  • 1
    Do you iterally want the " and + characters to appear in the output as shown? Commented Nov 6, 2013 at 15:52
  • Please edit the question and provide a well-formed input sample, currently there are two start tags <content> which are nowhere closed. Commented Nov 6, 2013 at 21:14

1 Answer 1

2

Assuming XSLT 2.0, here is some suggestion on how to approach that, assuming you really want some string output with quotes and plus symbols (to get Javascript or similar code to construct XML as a string?):

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

<xsl:output method="text"/>

<xsl:template match="*">
  <xsl:param name="name" select="name()"/>
  <xsl:text>&lt;</xsl:text>
  <xsl:value-of select="$name"/>
  <xsl:apply-templates select="@*"/>
  <xsl:text>&gt;</xsl:text>
  <xsl:apply-templates/>
  <xsl:text>&lt;/</xsl:text>
  <xsl:value-of select="$name"/>
  <xsl:text>&gt;</xsl:text>
</xsl:template>

<xsl:template match="@*">
  <xsl:param name="name" select="name()"/>
  <xsl:text> </xsl:text>
  <xsl:value-of select="$name"/>
  <xsl:text>='</xsl:text>
  <xsl:value-of select="."/>
  <xsl:text>'</xsl:text>
</xsl:template>

<xsl:template match="text()[matches(., '^\s+$')]">
  <xsl:text>"
+"</xsl:text>
</xsl:template>

<xsl:template match="/children">
  <xsl:text>"</xsl:text>
  <xsl:next-match>
    <xsl:with-param name="name" select="'root'"/>
  </xsl:next-match>
  <xsl:text>"</xsl:text>
</xsl:template>

<xsl:template match="child">
  <xsl:next-match>
    <xsl:with-param name="name" select="'item'"/>
  </xsl:next-match>
</xsl:template>

<xsl:template match="child//child">
  <xsl:variable name="copy" as="element()">
    <xsl:copy>
      <xsl:attribute name="parent_id" select="ancestor::child[1]/@data"/>
      <xsl:copy-of select="@* , node()"/>
    </xsl:copy>
  </xsl:variable>
  <xsl:apply-templates select="$copy"/>
</xsl:template>

</xsl:stylesheet>

That transforms the input

<children>
    <child data="test1">
     <content><name>test1</name></content>
     <child>
      <content><name>test1child</name></content>
     </child>
    </child>
</children>

into the result

"<root>"
+"<item data='test1'>"
+"<content><name>test1</name></content>"
+"<item parent_id='test1'>"
+"<content><name>test1child</name></content>"
+"</item>"
+"</item>"
+"</root>"

The code so far has many shortcomings however as it would not construct well-formed XML with properly escaped attribute values and also does not care to output namespace declarations. You could however adapt more sophisticated solutions like http://lenzconsulting.com/xml-to-string/.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.