Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • pisces113 10 posts 30 karma points
    Mar 04, 2012 @ 15:17
    pisces113
    0

    xml to xml using xslt

    Hi there,

    I am new to this group and to xml.  I have to format an output file to xml using xlst.

     

    I have the following structure for the xml which is dervied from MS REporting Services:

    Job Details    - Header

      Job Number  - Always 1 Job Number can have 1 or more ItemDetails

          ItemDetails - 1 or more for each Job Number

                ItemNumber

                ItemSorCode

                ItemSorName

                Job_Item_Quantity

                ItemWidth

                ItemLength

                ItemDepth

          ItemDetails 

    Job Details

     

    Can someone please help with the transformation.  Any help, pointers much appreciated.

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Mar 04, 2012 @ 21:43
    Chriztian Steinmeier
    0

    Hi pisces113 (great name, btw :-)

    XML to XML transformation is usually very simple with XSLT. There are two main roads to follow:

    1. If you only need to cherry-pick a couple of values, use the Pull Approach.

    2. If you need most of the original data, but reformat some of them (e.g., different wrapper, convert certain attributes to elements, etc.), use the Push Approach.

    Here's a basic example of each method:

    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    >
    
        <!-- Basic *Pull Approach* example: -->
    
        <xsl:template match="/">
    <!-- Create a wrapper and count all ItemDetails in file -->
            <extract totalCount="{count(//ItemDetails)}">
                <!-- Grab a single (but entire) record and copy to output -->
                <xsl:copy-of select="//ItemDetails[ItemNumber = 123456]" />
            </extract>
        </xsl:template>
    
    </xsl:stylesheet>
    
    
    
    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    >
    
        <!-- Basic *Push Approach* example: -->
    
        <!-- Identity transform -->
        <xsl:template match="* | text()">
            <xsl:copy>
                <xsl:copy-of select="@*" />
                <xsl:apply-templates select="* | text()" />
            </xsl:copy>
        </xsl:template>
    
        <!-- Special template to correct all <ItemWidth> elements: -->
        <xsl:template match="ItemWidth">
            <xsl:copy>
                <xsl:value-of select=". * 10" />
            </xsl:copy>
        </xsl:template>
    
    </xsl:stylesheet>

    So, maybe you should try posting an example of the actual input XML you have, and the desired output XML you need?

    /Chriztian

  • pisces113 10 posts 30 karma points
    Mar 04, 2012 @ 22:03
    pisces113
    0

    Thanks Chriztian,

     

    Here is a sample of my xml. This just shows 1 itemdetail for each job.  However, each job can have more than 1 itemdetail.

    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <JobFile>
    <JobDetails>
    <JobNumber>90903</JobNumber>
    <ItemDetails>
    <ItemNumber>10</ItemNumber>
    <ItemSorCode>CY00478</ItemSorCode>
    <ItemSorName>Provide necessary resources to site, in order to carry out welding and metal work repairs to fire barriers.</ItemSorName>
    <ItemQuantity>1.00</ItemQuantity>
    <ItemWidth>0</ItemWidth>
    <ItemLength>0</ItemLength>
    <ItemDepth>0</ItemDepth>
    </ItemDetails>
    </JobDetails>
    </JobFile>

    TIA

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Mar 04, 2012 @ 22:17
    Chriztian Steinmeier
    0

    - and what should the above be transformed into? What do you expect as output?

    /Chriztian

  • pisces113 10 posts 30 karma points
    Mar 05, 2012 @ 13:29
    pisces113
    0

    Sorry that's the output I require.  Here is the source xml

      <?xml version="1.0" encoding="iso-8859-1" ?>
    - <Report Name="Conway 0650 Job items">
    - <table1>
    - <table1_JobNumber_Collection>
    - <table1_JobNumber JobNumber="3401">
    - <Detail_Collection>
      <Detail ItemNumber="10" ItemSorCode="H0101" ItemSorName="Take up 305mm x 200mm granite kerb, re-square ends as necessary and stack for re-use. Break out 150mm thick concrete foundation and concrete haunch. Load and cart waste to tip." job_item_quantity="2.00" ItemWidth="0.00" ItemLEngth="2.00" ItemDepth="0.00" />
      <Detail ItemNumber="10" ItemSorCode="H0101" ItemSorName="Take up 305mm x 200mm granite kerb, re-square ends as necessary and stack for re-use. Break out 150mm thick concrete foundation and concrete haunch. Load and cart waste to tip." job_item_quantity="2.00" ItemWidth="0.00" ItemLEngth="2.00" ItemDepth="0.00" />
      <Detail ItemNumber="10" ItemSorCode="H0101" ItemSorName="Take up 305mm x 200mm granite kerb, re-square ends as necessary and stack for re-use. Break out 150mm thick concrete foundation and concrete haunch. Load and cart waste to tip." job_item_quantity="2.00" ItemWidth="0.00" ItemLEngth="2.00" ItemDepth="0.00" />
      <Detail ItemNumber="20" ItemSorCode="H0104" ItemSorName="Lay 305mm x 200mm granite kerb to Clause 1109.1AR with 150mm thick, grade C7.5P (ST1) concrete foundation and grade C7.5P (ST1) concrete haunch. Include laying to radius, angled or dropped kerbs with flush or 20mm kerb face." job_item_quantity="2.00" ItemWidth="0.00" ItemLEngth="2.00" ItemDepth="0.00" />
      <Detail ItemNumber="20" ItemSorCode="H0104" ItemSorName="Lay 305mm x 200mm granite kerb to Clause 1109.1AR with 150mm thick, grade C7.5P (ST1) concrete foundation and grade C7.5P (ST1) concrete haunch. Include laying to radius, angled or dropped kerbs with flush or 20mm kerb face." job_item_quantity="2.00" ItemWidth="0.00" ItemLEngth="2.00" ItemDepth="0.00" />
      <Detail ItemNumber="20" ItemSorCode="H0104" ItemSorName="Lay 305mm x 200mm granite kerb to Clause 1109.1AR with 150mm thick, grade C7.5P (ST1) concrete foundation and grade C7.5P (ST1) concrete haunch. Include laying to radius, angled or dropped kerbs with flush or 20mm kerb face." job_item_quantity="2.00" ItemWidth="0.00" ItemLEngth="2.00" ItemDepth="0.00" />
      </Detail_Collection>
      </table1_JobNumber>

    this is repeated....

  • pisces113 10 posts 30 karma points
    Mar 05, 2012 @ 13:38
    pisces113
    0

    input                                                                Transformed Output

    <table1_JobNumber JobNumber>                       = <JobNumber>

    <Detail_Collection>                                           = <ItemDetails>

    <Detail

     ItemNumber                                                     =  ItemNumber

    ItemSorCode                                                     =  ItemSorCode

    ItemSorName                                                    =  ItemSorName

    job_item_quantity                                              =  ItemQuantity

    ItemWidth                                                         = ItemWidth

    ItemLEngth                                                       = ItemLength

    ItemDepth                                                         = ItemDepth   >

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Mar 05, 2012 @ 21:46
    Chriztian Steinmeier
    0

    Hi again,

    See what you can do with these templates:

    <xsl:template match="table1_JobNumber_Collection">
        <JobFile>
            <JobDetails>
                <JobNumber>
                    <xsl:value-of select="table1_JobNumber/@JobNumber" />
                </JobNumber>
    
                <xsl:apply-templates select="table1_JobNumber/Detail_Collection" />
    
            </JobDetails>
        </JobFile>
    </xsl:template>
    
    <xsl:template match="Detail_Collection">
        <ItemDetails>
            <xsl:apply-templates />
        </ItemDetails>
    </xsl:template>
    
    <xsl:template match="Detail">
        <!-- Process all the attributes -->
        <xsl:apply-templates select="@*" />
    </xsl:template>
    
    <!-- Most attributes transforms to an element -->
    <xsl:template match="Detail/@*">
        <xsl:element name="{name()}">
            <xsl:value-of select="." />
        </xsl:element>
    </xsl:template>
    
    <!-- Not this one, though -->
    <xsl:template match="Detail/@job_item_quantity">
        <ItemQuantity>
            <xsl:value-of select="." />
        </ItemQuantity>
    </xsl:template>
    
    <!-- And this one had a typo ... -->
    <xsl:template match="Detail/@ItemLEngth">
        <ItemLength>
            <xsl:value-of select="." />
        </ItemLength>
    </xsl:template>
    

    How are you performing the actual transform - through Umbraco or something completely different? 

    /Chriztian

  • seess 3 posts 23 karma points
    Mar 06, 2012 @ 00:44
    seess
    0

    Your XML file seems to be wrong. You can only have one root element.

    1 or more for each Job Number

                ItemNumber

                ItemSorCode

                ItemSorName

                Job_Item_Quantity

                ItemWidth

                ItemLength

                ItemDepth

          ItemDetails 

  • pisces113 10 posts 30 karma points
    Mar 06, 2012 @ 07:05
    pisces113
    0

    thanks Chriztian

  • pisces113 10 posts 30 karma points
    Mar 08, 2012 @ 20:57
    pisces113
    0

    Thanks for your help Chriztian!!    I applied the stylesheet and the output looks MUCH better than what I had.  There is one small issue.

    There can be many <itemDetails> within a <JobNumber> and the <JobNumber> is not being shown.  It's only showing for the FIRST <JobNumber>

    So, wt the moment, only the FIRST <JobNumber> is given and <ItemDetails> closes after that <JobNumber>

    <ItemDetails> then begins again for the new <JobNumber> even though the JobNumber is not shown.

     

    So I have this

    <Job Details>
        <JobNumber> </JobNumber>
       <ItemDetails>
           <itemNumber>  </ItemNumber>  --1st Item for this <JobNumber>
    <itemSorCode>  </ItemSorCode>
    <itemSorName>  </ItemSorName>
    <JobItemQuantity>  </JobItemQuantity>
    <itemWidth>  </ItemWidth>
    <itemLength>  </ItemLength>
    <itemDepth>  </ItemDepth>

           <itemNumber>  </ItemNumber>    --2nd item for this <JobNumber>
    <itemSorCode>  </ItemSorCode>
    <itemSorName>  </ItemSorName>
    <JobItemQuantity>  </JobItemQuantity>
    <itemWidth>  </ItemWidth>
    <itemLength>  </ItemLength>
    <itemDepth>  </ItemDepth>

           <itemNumber>  </ItemNumber> --3rd item for this <JobNumber>
    <itemSorCode>  </ItemSorCode>
    <itemSorName>  </ItemSorName>
    <JobItemQuantity>  </JobItemQuantity>
    <itemWidth>  </ItemWidth>
    <itemLength>  </ItemLength>
    <itemDepth>  </ItemDepth>

           <itemNumber>  </ItemNumber>   -- 4th item for this <JobNumber>
    <itemSorCode>  </ItemSorCode>
    <itemSorName>  </ItemSorName>
    <JobItemQuantity>  </JobItemQuantity>
    <itemWidth>  </ItemWidth>
    <itemLength>  </ItemLength>
    <itemDepth>  </ItemDepth>

    </ItemDetails>  -- This close for the current <JobNumber>

    <ItemDetails>  -- Start of a new <JobNumber>

    But the <JobNumber> node is missing here.
    The xml follows like this (after <ItemDetails>:

     <itemNumber>  </ItemNumber>
    <itemSorCode>  </ItemSorCode>
    <itemSorName>  </ItemSorName>
    <JobItemQuantity>  </JobItemQuantity>
    <itemWidth>  </ItemWidth>
    <itemLength>  </ItemLength>
    <itemDepth>  </ItemDepth>

    TIA

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Mar 08, 2012 @ 23:10
    Chriztian Steinmeier
    0

    Yeah, that makes total sense the way he coded it (me, that is :-)

    You need to change the table1_JobNumber_Collection template and add another for table1_JobNumber, like this:

    <!-- Changed template -->
        <xsl:template match="table1_JobNumber_Collection">
            <JobFile>
                <JobDetails>
                    <xsl:apply-templates select="table1_JobNumber" />
                </JobDetails>
            </JobFile>
        </xsl:template>
    
    <!-- New template -->
        <xsl:template match="table1_JobNumber"> <JobNumber> <xsl:value-of select="@JobNumber" /> </JobNumber> <xsl:apply-templates select="Detail_Collection" /> </xsl:template>
    
    Leave the rest as it was and *now* you should be pretty close (hard to see if you need a wrapper around every set of JobNumber + ItemDetails).
    Just let me know if it works!

    /Chriztian 

  • pisces113 10 posts 30 karma points
    Mar 09, 2012 @ 20:36
    pisces113
    0

    Will give that a go.  Thanks for your help Chriztian!!

  • pisces113 10 posts 30 karma points
    Mar 12, 2012 @ 17:08
    pisces113
    0

    Hi Chriztian,

    It needs a bit of tweaking:

    I need an ItemDetails tag before each <ItemNumber> and after each closing <ItemDepth> tag

    also a <Job Details> tag after each <ItemDeatils> for each Job

     

    Like this:

    - <JobDetails>
      <JobNumber>10411141</JobNumber>
    - <ItemDetails>
      <ItemNumber>10</ItemNumber>
      <ItemSorCode>CY02601</ItemSorCode>
      <ItemSorName>Collect litter bin from depot and deliver to site.</ItemSorName>
      <ItemQuantity>1.00</ItemQuantity>
      <ItemWidth>0</ItemWidth>
      <ItemLength>0</ItemLength>
      <ItemDepth>0</ItemDepth>
      </ItemDetails>
    - <ItemDetails>
      <ItemNumber>20</ItemNumber>
      <ItemSorCode>CY02606</ItemSorCode>
      <ItemSorName>Break out and cart litter bin to tip or depot, including removal of 4 no bolts in any footway material and reinstate with mortar.</ItemSorName>
      <ItemQuantity>1.00</ItemQuantity>
      <ItemWidth>0</ItemWidth>
      <ItemLength>0</ItemLength>
      <ItemDepth>0</ItemDepth>
      </ItemDetails>
    - <ItemDetails>
      <ItemNumber>30</ItemNumber>
      <ItemSorCode>CY02605</ItemSorCode>
      <ItemSorName>Fix litter bin in any footway material including take up existing material, cutting and reinstatement</ItemSorName>
      <ItemQuantity>1.00</ItemQuantity>
      <ItemWidth>0</ItemWidth>
      <ItemLength>0</ItemLength>
      <ItemDepth>0</ItemDepth>
      </ItemDetails>
      </JobDetails>

    Here is my xslt in its entirety:

    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008"
                xmlns:rdl="http://schemas.microsoft.com/sqlserver/reporting/2008">


            <xsl:template match="table1_JobNumber_Collection">
                <JobFile>
                    <JobDetails>
                      
                              <xsl:apply-templates select="table1_JobNumber" />
                    </JobDetails>
                </JobFile>
            </xsl:template>


     
     
      <xsl:template match="Detail_Collection">
                <ItemDetails>
                    <xsl:apply-templates />
                </ItemDetails>
            </xsl:template>

      <xsl:template match = "Detail">
        <xsl:apply-templates select = "@*"/>
      </xsl:template>
           
            <xsl:template match = "Detail/@*">
               
                   <xsl:element name="{name()}">
                    <xsl:value-of select="." />
                </xsl:element>
            </xsl:template>
     
      <xsl:template match="table1_JobNumber">
        <JobNumber>
          <xsl:value-of select="@JobNumber"/>
        </JobNumber>
        <xsl:apply-templates select="Detail_Collection" />
      </xsl:template>

      <xsl:template match="Detail/@ItemNumber">
        <ItemNumber>
          <xsl:value-of select ="."/>
        </ItemNumber>
      </xsl:template>
     
      <xsl:template match="Detail/@ItemSorCode">
        <ItemSorCode>
          <xsl:value-of select ="."/>
        </ItemSorCode>
      </xsl:template>

      <xsl:template match="Detail/@ItemSorName">
        <ItemSorName>
          <xsl:value-of select ="."/>
        </ItemSorName>
      </xsl:template>

      <xsl:template match="Detail/@job_item_quantity">
        <JobItemQuantity>
          <xsl:value-of select ="."/>
        </JobItemQuantity>
      </xsl:template>

      <xsl:template match="Detail/@ItemWidth">
        <ItemWidth>
          <xsl:value-of select ="."/>
        </ItemWidth>
      </xsl:template>

      <xsl:template match="Detail/@ItemLEngth">
        <ItemLength>
          <xsl:value-of select ="."/>
        </ItemLength>
      </xsl:template>

      <xsl:template match="Detail/@ItemDepth">
        <ItemDepth>
          <xsl:value-of select ="."/>
        </ItemDepth>
      </xsl:template>
     
    </xsl:stylesheet>

    TIA

  • pisces113 10 posts 30 karma points
    Mar 18, 2012 @ 12:16
    pisces113
    0
  • pisces113 10 posts 30 karma points
    May 13, 2012 @ 09:35
    pisces113
    0

    Can anybody help with the above?  I'm still stuck

     

    TIA

Please Sign in or register to post replies

Write your reply to:

Draft