2

I have an xml in the following format:

<?xml version="1.0" encoding="UTF-8"?>
<response>
   <cases>
      <case>CASE-ONE</case>
      <case>CASE-TWO</case>
   </cases>
   <results>
      <Final-Results>
         <issues>
            <row>
               <IKEY>2014-03-26-05.22.22.193840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </Final-Results>
      <Final-Results>
         <issues>
            <row>
               <IKEY>2014-03-26-05.05.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
            <row>
               <IKEY>2014-03-26-05.10.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </Final-Results>
   </results>
</response>

Now, I want to convert the above xml to the following format using XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<response>
   <cases>
      <case>
         CASE-ONE
         <issues>
            <row>
               <IKEY>2014-03-26-05.22.22.193840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </case>
      <case>
         CASE-TWO
         <issues>
            <row>
               <IKEY>2014-03-26-05.05.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
            <row>
               <IKEY>2014-03-26-05.10.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </case>
   </cases>
</response>

The idea is to move the content between the first <issues> </issues> tags to the first <case> </case> tags and the second <issues> </issues> tags to the second tags and so on. Here the number of <case> tags and <issues> tags are uncertain. So,I think I have to use for loop kind of thing here.Honestly, I am not expert in using XSLT. It would be great if you can provide a solution. Please feel free to add a comment if my question is not clear so that I can put it in better words. Thanks in advance.

1
  • If you have control over the design of your output document I'd advise against using mixed content like this <case>CASE-ONE<issues><row>... You should wrap the case name in a name tag like <case><name>CASE-ONE</name><issues>... or something similar that semantically fits your needs. Commented Apr 17, 2014 at 6:35

3 Answers 3

3

No need to use a for loop. Use the identity transform and xsl:apply-templates instead.

XML Input

<response>
    <cases>
        <case>CASE-ONE</case>
        <case>CASE-TWO</case>
    </cases>
    <results>
        <Final-Results>
            <issues>
                <row>
                    <IKEY>2014-03-26-05.22.22.193840T01</IKEY>
                    <PRTY>999</PRTY>
                </row>
            </issues>
        </Final-Results>
        <Final-Results>
            <issues>
                <row>
                    <IKEY>2014-03-26-05.05.51.077840T01</IKEY>
                    <PRTY>999</PRTY>
                </row>
                <row>
                    <IKEY>2014-03-26-05.10.51.077840T01</IKEY>
                    <PRTY>999</PRTY>
                </row>
            </issues>
        </Final-Results>
    </results>
</response>

XSLT 1.0

<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="/*">
        <xsl:copy>
            <xsl:apply-templates select="@*|cases"/>
        </xsl:copy>        
    </xsl:template>

    <xsl:template match="case">
        <xsl:variable name="pos" select="position()"/>
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:apply-templates select="/*/results/Final-Results[position()=$pos]/issues"/>
        </xsl:copy>        
    </xsl:template>

</xsl:stylesheet>

XML Output

<response>
   <cases>
      <case>CASE-ONE<issues>
            <row>
               <IKEY>2014-03-26-05.22.22.193840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </case>
      <case>CASE-TWO<issues>
            <row>
               <IKEY>2014-03-26-05.05.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
            <row>
               <IKEY>2014-03-26-05.10.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </case>
   </cases>
</response>
Sign up to request clarification or add additional context in comments.

Comments

1

I could think of this way:

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

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <response>
        <cases>
            <xsl:apply-templates select="response/cases/case"/>
        </cases>
    </response>
</xsl:template>
<xsl:template match="cases/case">
    <xsl:variable name="pos" select="position()"/>
    <xsl:copy>
        <xsl:value-of select="."/>
        <xsl:copy-of select="//response/results/Final-Results[position() = $pos]/issues"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

Comments

1

The following stylesheet produces the desired result:

<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="case">
        <case>
            <xsl:value-of select="concat('&#xa;', ., '&#xa;')" />
            <xsl:copy-of
                select="../../results/Final-Results[
            count(current()/preceding-sibling::case) + 1]/issues" />
        </case>
    </xsl:template>
    <xsl:template match="results" />
</xsl:stylesheet>

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.