Page 1 of 1

XSLT help

Posted: Mon Nov 11, 2019 12:07 pm
by LasseThid
I need to split an incoming xml-file into one xml-file per product in the order.
I have created an XSLT that will pick up all information except for the job-name.
Any ideas what might be wrong with my XSLT?

Incoming xml file

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<order version="1.0" type="order" order-id="26779" status="1" external-order-id="Weborder 103591/105658/105660" external-cost-center="" created-date="11/08/2019 16:15:35" order-date="11/08/2019 16:15:35" user-id="a.b@c.com" customer-id="2" customer-name="Customer Name" external-customer-id="2036" organization-id="081646" vat-id="" sales-person="" project-manager="csr" currency="SEK" portal-id="2" portal-name="Customer Name">
	<information />
	<jobs>
		<job id="5008" type="print" status="1" name="Businessscard 4+4" job-name="Businesscard 1">
			<information />
			<fields>
				<field name="climatecompensation">Climatecompensated</field>
			</fields>
			<producttype>indigo_stationary_businesscard</producttype>
			<productionunit>a3_print</productionunit>
			<quantity>250</quantity>
			<instructions />
			<part type="inlay">
				<pages>2</pages>
				<sides>TwoSidedHeadToHead</sides>
				<color>CMYK</color>
				<finaldimension>90x50</finaldimension>
				<printdimension>460x320</printdimension>
				<media item-number="Indigo-0241" weight="300" dimension="460x320" grain-direction="ShortEdge">Profimatt</media>
				<nup>24</nup>
			</part>
		</job>
		<job id="5009" type="print" status="1" name="Businessscard 4+4" job-name="Businesscard 2">
			<information />
			<fields>
				<field name="climatecompensation">Climatecompensated</field>
			</fields>
			<producttype>indigo_stationary_businesscard</producttype>
			<productionunit>a3_print</productionunit>
			<quantity>250</quantity>
			<instructions />
			<part type="inlay">
				<pages>2</pages>
				<sides>TwoSidedHeadToHead</sides>
				<color>CMYK</color>
				<finaldimension>90x50</finaldimension>
				<printdimension>460x320</printdimension>
				<media item-number="Indigo-0241" weight="300" dimension="460x320" grain-direction="ShortEdge">Profimatt</media>
				<nup>24</nup>
			</part>
		</job>
		<job id="5010" type="print" status="1" name="Businessscard 4+4" job-name="Businesscard 3">
			<information />
			<fields>
				<field name="climatecompensation">Climatecompensated</field>
			</fields>
			<producttype>indigo_stationary_businesscard</producttype>
			<productionunit>a3_print</productionunit>
			<quantity>250</quantity>
			<instructions />
			<part type="inlay">
				<pages>2</pages>
				<sides>TwoSidedHeadToHead</sides>
				<color>CMYK</color>
				<finaldimension>90x50</finaldimension>
				<printdimension>460x320</printdimension>
				<media item-number="Indigo-0241" weight="300" dimension="460x320" grain-direction="ShortEdge">Profimatt</media>
				<nup>24</nup>
			</part>
		</job>
	</jobs>
</order>
XSLT:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <job>
            <jobname>
                <xsl:value-of select="//order/jobs/job/job-name"/>
            </jobname>
            <quantity>
                <xsl:value-of select="//order/jobs/job/quantity"/>
            </quantity>
            <sides>
                <xsl:value-of select="//order/jobs/job/part/sides"/>
            </sides>
            <finaldimension>
                <xsl:value-of select="//order/jobs/job/part/finaldimension"/>
            </finaldimension>
            <printdimension>
                <xsl:value-of select="//order/jobs/job/part/printdimension"/>
            </printdimension>
        </job>
    </xsl:template>
</xsl:stylesheet>
Resulting xml-file:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<job>
   <jobname/>
   <quantity>250</quantity>
   <sides>TwoSidedHeadToHead</sides>
   <finaldimension>90x50</finaldimension>
   <printdimension>460x320</printdimension>
</job>
What I'm looking for is for the node jobname to read <jobname>Businesscard 1</jobname>

Thanks in advance!

Re: XSLT help

Posted: Mon Nov 11, 2019 12:50 pm
by Arthur
Have you had a chance to find out if the path to the nod you are referring to, resolved with a correct value in Switch ??
Navigate in Switch to "//order/jobs/job/job-name" of that XML and see if it is correct. If other paths to certain nodes are getting you the right result and they all are defined in the XSLT in the same fashion, I would suspect sth with how the Path to that particular problematic value is defined (as it is with a dash or so) .....

Sorry if this does not make sense, had a long and difficult night with a baby :lol: ....

Re: XSLT help

Posted: Mon Nov 11, 2019 1:02 pm
by jan_suhr
Try this:

Code: Select all

 <xsl:value-of select="//order/jobs/job/@job-name"/>

Re: XSLT help

Posted: Mon Nov 11, 2019 1:59 pm
by LasseThid
Thanks Jan.

That did the trick.
Can you explain why I need to use @job-name for this node when everything else works without the @-character?

Re: XSLT help

Posted: Mon Nov 11, 2019 1:59 pm
by LasseThid
Thanks Jan.

That did the trick.
Can you explain why I need to use @job-name for this node when everything else works without the @-character?

Re: XSLT help

Posted: Mon Nov 11, 2019 2:08 pm
by billy.olvestad
job-name in your case is an attribute to the node "job", not an element with a text node directly under "job". The other values are elements with text nodes directly under "job".
That's why you need the @-character. It means "attribute" in xslt.

Re: XSLT help

Posted: Mon Nov 11, 2019 2:08 pm
by LasseThid
Arthur wrote:
Mon Nov 11, 2019 12:50 pm
Have you had a chance to find out if the path to the nod you are referring to, resolved with a correct value in Switch ??
Navigate in Switch to "//order/jobs/job/job-name" of that XML and see if it is correct. If other paths to certain nodes are getting you the right result and they all are defined in the XSLT in the same fashion, I would suspect sth with how the Path to that particular problematic value is defined (as it is with a dash or so) .....

Sorry if this does not make sense, had a long and difficult night with a baby :lol: ....
Hi Arthur.
I haven't tried it in Switch yet as I'm just trying to figure out how to set up the XSLT. XSLT is something I have no knowledge about at all, so I'm learning by trial and error... :lol:
I guess I could have created a test flow and add the xml file as metadata to itself, but I was testing it in XMLSpear when I noticed it didn't work, so I figured I'd better ask the experts...

Re: XSLT help

Posted: Mon Nov 11, 2019 2:11 pm
by LasseThid
billy.olvestad wrote:
Mon Nov 11, 2019 2:08 pm
job-name in your case is an attribute to the node "job", not a text node directly under. The other values are text nodes directly under "job".
That's why you need the @-character. It means "attribute" in xslt.
Thanks for the information.
It's kinda hard to understand why some things work while others doesn't when you don't know what you're doing... :lol:

Re: XSLT help

Posted: Mon Nov 11, 2019 2:15 pm
by billy.olvestad
LasseThid wrote:
Mon Nov 11, 2019 2:11 pm
Thanks for the information.
It's kinda hard to understand why some things work while others doesn't when you don't know what you're doing... :lol:
I know. I have pulled my hair a lot when learning XSLT :) .
In this case it was a simple error, but XSLT in general is not the most intuitive thing, so sometimes it takes a lot of trial and error.
But it is seriously powerful when you get to know it.

Re: XSLT help

Posted: Mon Nov 11, 2019 2:21 pm
by LasseThid
Yeah.
I have both the XML for Dummies and the XSLT for Dummies here at work. Perhaps I should bring them and do some reading on the train to Stockholm tonight. :roll:

Re: XSLT help

Posted: Mon Nov 18, 2019 12:30 pm
by LasseThid
Ok, so the XSLT works fine for one product, but if the xml file contains more than one product I get the same result repeated for every product.
I added an <xsl:for-each> loop, but it seems to pick up the first product every time.
How can I get one <job> for each product?

Incoming xml:

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<order version="1.0" type="order" order-id="26779" status="1" external-order-id="Weborder 103591/105658/105660" external-cost-center="" created-date="11/08/2019 16:15:35" order-date="11/08/2019 16:15:35" user-id="a.b@c.se" customer-id="2" customer-name="kundnamn" external-customer-id="2036" organization-id="081646" vat-id="" sales-person="" project-manager="CSR" currency="SEK" portal-id="2" portal-name="Portalnamn">
	<information />
	<fields>
		<field name="Reference">Kund</field>
		<field name="extend">True</field>
	</fields>
	<customer>
		<fields>
			<field name="API-nyckel">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</field>
			<field name="Systemkod">haikom</field>
		</fields>
	</customer>
	<buyer>
		<company>Företag</company>
		<name>Namn</name>
		<email />
		<phone />
		<mobilephone />
	</buyer>
	<payment type="Invoice">
		<billingaddress e-invoice-code="" email="">
			<name>Namn</name>
			<address1>Adress</address1>
			<address2 />
			<address3 />
			<city>Stad</city>
			<zipcode>Postnr</zipcode>
			<country>Sweden</country>
			<countrycode>SE</countrycode>
			<state />
		</billingaddress>
	</payment>
	<items>
		<item type="Template" item-number="201" name="Visitkort 4+4 (Motiv 1)" account-code="" external-cost-center="" quantity="250" unit-price="x,xxx" unit="pcs" total-price="xxx,xxx" vat-code="1" vat="25,00" weight="0,337" template-id="159ac08b349a4b8390693fb952e0e694">
			<information />
			<deliveries>
				<delivery delivery-id="2b102f364c214f96b78f712de7417275" quantity="250" />
			</deliveries>
			<jobs>
				<job id="5008" />
			</jobs>
		</item>
		<item type="Template" item-number="201" name="Visitkort 4+4 (Motiv 2)" account-code="" external-cost-center="" quantity="250" unit-price="x,xxxx" unit="pcs" total-price="xxx,xxx" vat-code="1" vat="25,00" weight="0,337" template-id="cd6955be74b044cb82ae61a6f8df5e29">
			<information />
			<deliveries>
				<delivery delivery-id="2b102f364c214f96b78f712de7417275" quantity="250" />
			</deliveries>
			<jobs>
				<job id="5009" />
			</jobs>
		</item>
		<item type="Template" item-number="201" name="Visitkort 4+4 (Motiv 3)" account-code="" external-cost-center="" quantity="250" unit-price="x,xxxx" unit="pcs" total-price="xxx,xxx" vat-code="1" vat="25,00" weight="0,337" template-id="e048f34e3a5a458aae2fe1dc0f805eb6">
			<information />
			<deliveries>
				<delivery delivery-id="2b102f364c214f96b78f712de7417275" quantity="250" />
			</deliveries>
			<jobs>
				<job id="5010" />
			</jobs>
		</item>
		<item type="Freight" item-number="Frakt" name="Frakt" account-code="bring_parcel" external-cost-center="" quantity="1" unit-price="xxx" unit="pcs" total-price="xxx" vat-code="1" vat="25,00" weight="0" template-id="">
			<information />
			<deliveries>
				<delivery delivery-id="2b102f364c214f96b78f712de7417275" quantity="1" />
			</deliveries>
			<jobs />
		</item>
	</items>
	<jobs>
		<job id="5008" type="print" status="1" name="Visitkort 4+4 (Motiv 1)" job-name="Motiv 1">
			<information />
			<fields>
				<field name="climatecompensation">Klimatkompenserad</field>
			</fields>
			<producttype>indigo_kontorstrycksaker_visitkort_korrespondenskort</producttype>
			<productionunit>a3_print</productionunit>
			<quantity>250</quantity>
			<instructions />
			<part type="inlay">
				<pages>2</pages>
				<sides>TwoSidedHeadToHead</sides>
				<color>CMYK</color>
				<finaldimension>90x50</finaldimension>
				<printdimension>460x320</printdimension>
				<media item-number="Indigo-0241" weight="300" dimension="460x320" grain-direction="ShortEdge">Papperskvalitet</media>
				<nup>24</nup>
			</part>
		</job>
		<job id="5009" type="print" status="1" name="Visitkort 4+4 (Motiv 2)" job-name="Motiv 2">
			<information />
			<fields>
				<field name="climatecompensation">Klimatkompenserad</field>
			</fields>
			<producttype>indigo_kontorstrycksaker_visitkort_korrespondenskort</producttype>
			<productionunit>a3_print</productionunit>
			<quantity>250</quantity>
			<instructions />
			<part type="inlay">
				<pages>2</pages>
				<sides>TwoSidedHeadToHead</sides>
				<color>CMYK</color>
				<finaldimension>90x50</finaldimension>
				<printdimension>460x320</printdimension>
				<media item-number="Indigo-0241" weight="300" dimension="460x320" grain-direction="ShortEdge">Papperskvalitet</media>
				<nup>24</nup>
			</part>
		</job>
		<job id="5010" type="print" status="1" name="Visitkort 4+4 (Motiv 3)" job-name="Motiv 3">
			<information />
			<fields>
				<field name="climatecompensation">Klimatkompenserad</field>
			</fields>
			<producttype>indigo_kontorstrycksaker_visitkort_korrespondenskort</producttype>
			<productionunit>a3_print</productionunit>
			<quantity>250</quantity>
			<instructions />
			<part type="inlay">
				<pages>2</pages>
				<sides>TwoSidedHeadToHead</sides>
				<color>CMYK</color>
				<finaldimension>90x50</finaldimension>
				<printdimension>460x320</printdimension>
				<media item-number="Indigo-0241" weight="300" dimension="460x320" grain-direction="ShortEdge">Papperskvalitet</media>
				<nup>24</nup>
			</part>
		</job>
	</jobs>
	<deliveries>
		<delivery id="2b102f364c214f96b78f712de7417275" shipping-method="Frakt">
			<name>Kundnamn</name>
			<address1>Adress</address1>
			<address2 />
			<address3 />
			<city>Stad</city>
			<zipcode>Postnr</zipcode>
			<country>Sweden</country>
			<countrycode>SE</countrycode>
			<state />
			<requesteddeliverydate>11/13/2019 00:00:00</requesteddeliverydate>
			<contactname>Mottagare</contactname>
			<contactemail>a.b@c.se</contactemail>
			<contactphone />
			<contactmobilephone />
			<deliveryinformation />
			<transportinstructions />
			<isexpress>False</isexpress>
			<fields />
			<consignments />
		</delivery>
	</deliveries>
</order>
XSLT

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
       <xsl:for-each select="//order/jobs/job">
         <job>
           <jobid>
                <xsl:value-of select="//order/jobs/job/@id"/>              
              </jobid>
            <jobname>
                <xsl:value-of select="//order/jobs/job/@job-name"/>
            </jobname>
            <quantity>
                <xsl:value-of select="//order/jobs/job/quantity"/>
            </quantity>
            <sides>
                <xsl:value-of select="//order/jobs/job/part/sides"/>
            </sides>
            <finaldimension>
                <xsl:value-of select="//order/jobs/job/part/finaldimension"/>
            </finaldimension>
            <printdimension>
                <xsl:value-of select="//order/jobs/job/part/printdimension"/>
            </printdimension>
        </job>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
Resulting xml

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<job>
   <jobid>5008</jobid>
   <jobname>Motiv 1</jobname>
   <quantity>250</quantity>
   <sides>TwoSidedHeadToHead</sides>
   <finaldimension>90x50</finaldimension>
   <printdimension>460x320</printdimension>
</job>
<job>
   <jobid>5008</jobid>
   <jobname>Motiv 1</jobname>
   <quantity>250</quantity>
   <sides>TwoSidedHeadToHead</sides>
   <finaldimension>90x50</finaldimension>
   <printdimension>460x320</printdimension>
</job>
<job>
   <jobid>5008</jobid>
   <jobname>Motiv 1</jobname>
   <quantity>250</quantity>
   <sides>TwoSidedHeadToHead</sides>
   <finaldimension>90x50</finaldimension>
   <printdimension>460x320</printdimension>
</job>
Desired result

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<job>
   <jobid>5008</jobid>
   <jobname>Motiv 1</jobname>
   <quantity>250</quantity>
   <sides>TwoSidedHeadToHead</sides>
   <finaldimension>90x50</finaldimension>
   <printdimension>460x320</printdimension>
</job>
<job>
   <jobid>5009</jobid>
   <jobname>Motiv 2</jobname>
   <quantity>250</quantity>
   <sides>TwoSidedHeadToHead</sides>
   <finaldimension>90x50</finaldimension>
   <printdimension>460x320</printdimension>
</job>
<job>
   <jobid>5010</jobid>
   <jobname>Motiv 3</jobname>
   <quantity>250</quantity>
   <sides>TwoSidedHeadToHead</sides>
   <finaldimension>90x50</finaldimension>
   <printdimension>460x320</printdimension>
</job>
Even better if I can get one xml per <job>... :D

Thanks in advance

Re: XSLT help

Posted: Mon Nov 18, 2019 2:20 pm
by LasseThid
A slightly modified XSLT

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
       <xsl:for-each select="//order/jobs/job">
         <job>
           <jobid>
                <xsl:value-of select="@id"/>              
              </jobid>
            <jobname>
                <xsl:value-of select="@job-name"/>
            </jobname>
            <quantity>
                <xsl:value-of select="/quantity"/>
            </quantity>
            <sides>
                <xsl:value-of select="/part/sides"/>
            </sides>
            <finaldimension>
                <xsl:value-of select="/part/finaldimension"/>
            </finaldimension>
            <printdimension>
                <xsl:value-of select="/part/printdimension"/>
            </printdimension>
        </job>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
gives me

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<job>
   <jobid>5008</jobid>
   <jobname>Motiv 1</jobname>
   <quantity/>
   <sides/>
   <finaldimension/>
   <printdimension/>
</job>
<job>
   <jobid>5009</jobid>
   <jobname>Motiv 2</jobname>
   <quantity/>
   <sides/>
   <finaldimension/>
   <printdimension/>
</job>
<job>
   <jobid>5010</jobid>
   <jobname>Motiv 3</jobname>
   <quantity/>
   <sides/>
   <finaldimension/>
   <printdimension/>
</job>
But why can't I pick up the other values?
If I set to path for <quantity> to //order/jobs/job/quantity all <quantity> nodes get the same result even if I change them to different values.

Re: XSLT help

Posted: Tue Nov 19, 2019 9:14 am
by LasseThid
Thanks for your help Jan.

From looking at your XSLT file I think I'm starting to understand what I did wrong in my XSLT file.