Page 1 of 2

XSLT help

Posted: Wed Feb 21, 2018 11:42 am
by Dave23
Alright all,

I'm having a slight issue trying to get this xslt to work. I'm just starting out with xslt so i've only got the basics working at the moment. Any help would be great.

Sample XML:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<Order_Root>
	<Header>
		<Info>Some Info</Info>
	</Header>
	<Order Number="1" Date="1/23/2018 10:53:00 AM">
		<OrderCharges Charge="0.00000" />
	</Order>
	<Order Number="2" Date="1/23/2018 10:53:00 AM">
		<OrderCharges Charge="0.00000" />
	</Order>
	<Order Number="3" Date="1/23/2018 10:53:00 AM">
		<OrderCharges Charge="0.00000" />
	</Order>
</Order_Root>
XSLT:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/Orders_Root/Header/Order">
        <xsl:result-document method="xml" href="{@Number}.xml">
            <xsl:copy-of select="." />
        </xsl:result-document>
    </xsl:template>

</xsl:stylesheet>
Currently this xslt splits the xml into 3 xml containing the Order and the filename as the @Number.

This is ok however i'm struggling with trying to put the Header into each xml.

So resulting in 3 xml files:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<Order_Root>
	<Header>
		<Info>Some Info</Info>
	</Header>
	<Order Number="1" Date="1/23/2018 10:53:00 AM">
		<OrderCharges Charge="0.00000" />
	</Order>
</Order_Root>

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<Order_Root>
	<Header>
		<Info>Some Info</Info>
	</Header>
	<Order Number="2" Date="1/23/2018 10:53:00 AM">
		<OrderCharges Charge="0.00000" />
	</Order>
</Order_Root>

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<Order_Root>
	<Header>
		<Info>Some Info</Info>
	</Header>
	<Order Number="3" Date="1/23/2018 10:53:00 AM">
		<OrderCharges Charge="0.00000" />
	</Order>
</Order_Root>

Re: XSLT help

Posted: Wed Feb 21, 2018 4:51 pm
by loicaigon

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="Order">
        <xsl:variable name="url">
           <xsl:text>/Users/ozalto/Desktop/xmls/</xsl:text> 
           <xsl:value-of select="@Number"/>
            <xsl:text>.xml</xsl:text> 
        </xsl:variable>
        <xsl:result-document method="xml" href="{$url}">
            <Order_Root>
                <xsl:copy-of select="parent::node()/Header"></xsl:copy-of>
                <xsl:copy-of select="." />
            </Order_Root>
        </xsl:result-document>
    </xsl:template>
</xsl:stylesheet>

Re: XSLT help

Posted: Wed Feb 21, 2018 7:57 pm
by Dave23
Hi cheers for the reply loicaigon.

I tried using the xslt that you supplied but it doesn't seem to output anything. Was i meant to tweak anything in the xslt?

Cheers

Re: XSLT help

Posted: Wed Feb 21, 2018 8:38 pm
by Dave23
apologies my fault working now. cheers

Re: XSLT help

Posted: Wed Feb 21, 2018 9:46 pm
by loicaigon
I should have precised indeed the base url had to changed ;)

Re: XSLT help

Posted: Thu Feb 22, 2018 12:32 pm
by Dave23
How would it work if the xml looked like this instead?

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<Order_Root>
   <Header Info="Some Info">
   <Order Number="1" Date="1/23/2018 10:53:00 AM">
      <OrderCharges Charge="0.00000" />
   </Order>
   <Order Number="2" Date="1/23/2018 10:53:00 AM">
      <OrderCharges Charge="0.00000" />
   </Order>
   <Order Number="3" Date="1/23/2018 10:53:00 AM">
      <OrderCharges Charge="0.00000" />
   </Order>
   </Header>
</Order_Root>
The xslt doesn't currently work when the header tag is moved.

Re: XSLT help

Posted: Mon Feb 26, 2018 3:37 pm
by loicaigon
That's logical. XSLT works with presumed xpaths expressions. As the structure changes, xslt will fail.

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="Order">
        <xsl:variable name="url">
            <xsl:text>/Users/ozalto/Desktop/xmls/</xsl:text> 
            <xsl:value-of select="@Number"/>
            <xsl:text>.xml</xsl:text> 
        </xsl:variable>
        <xsl:result-document method="xml" href="{$url}">
            <Order_Root>
                <xsl:copy>
                    <xsl:apply-templates select="*|@*"></xsl:apply-templates>
                    <xsl:variable name="parent" select="parent::node()"/>
                    <xsl:element name="{$parent/name()}">
                      <xsl:for-each select="$parent/@*">
                          <xsl:copy></xsl:copy>
                      </xsl:for-each>
                    </xsl:element>
                </xsl:copy>
            </Order_Root>
        </xsl:result-document>
    </xsl:template>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Re: XSLT help

Posted: Tue Feb 27, 2018 1:07 pm
by Dave23
Cheers loicaigon. im slowly starting to understand..

Re: XSLT help

Posted: Tue Feb 27, 2018 2:26 pm
by loicaigon
The latter is a bit tougher cause it brings some more advanced concepts like the identity template but basically it consists in duplicating contents that is needed (Order and children) and place the parent (Header) inside. As the Header contains children, we cannot use the identity template this time or it will cause neverending loops. So we have to deal with it manually (hence the look for attributes).

Re: XSLT help

Posted: Tue Feb 27, 2018 2:28 pm
by loicaigon
The latter is a bit tougher cause it brings some more advanced concepts like the identity template but basically it consists in duplicating contents that is needed (Order and children) and place the parent (Header) inside. As the Header contains children, we cannot use the identity template this time or it will cause neverending loops. So we have to deal with it manually (hence the look for attributes).

Re: XSLT help

Posted: Wed Apr 18, 2018 12:54 am
by actionHero
I'm getting lost on how to make Switch move files to the next folder location. They are just going to the desktop.

Re: XSLT help

Posted: Wed Apr 18, 2018 1:55 pm
by Padawan
I think you can change that by using a relative output path instead of an absolute. I tested this in the Saxon configurator and you get all output files in the output folder. You can choose to output them in one folder by setting "Collect Results" to Yes.

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="Order">
        <xsl:variable name="url">
            <xsl:text>./</xsl:text>
            <xsl:value-of select="@Number"/>
            <xsl:text>.xml</xsl:text>
        </xsl:variable>
        <xsl:result-document method="xml" href="{$url}">
            <Order_Root>
                <xsl:copy>
                    <xsl:apply-templates select="*|@*"></xsl:apply-templates>
                    <xsl:variable name="parent" select="parent::node()"/>
                    <xsl:element name="{$parent/name()}">
                      <xsl:for-each select="$parent/@*">
                          <xsl:copy></xsl:copy>
                      </xsl:for-each>
                    </xsl:element>
                </xsl:copy>
            </Order_Root>
        </xsl:result-document>
    </xsl:template>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Re: XSLT help

Posted: Wed Apr 18, 2018 7:11 pm
by actionHero
Here's the error I get in the configurator. Switch is passing an incorrect parameter to the configurator, "-xsltversion".

Processing failed with the following error: Command line option -xsltversion is not recognized. Options available: -? -a -catalog -config -cr -diag -dtd -ea -expand -explain -export -ext -im -init -it -jit -l -lib -license -m -nogo -now -o -opt -or -outval -p -quit -r -relocate -repeat -s -sa -scmin -strip -t -T -target -TB -threads -TJ -Tlevel -Tout -TP -traceout -tree -u -val -versionmsg -warnings -x -xi -xmlversion -xsd -xsdversion -xsiloc -xsl -y


Here is what the configurator is passing:

Saxon command line: java -cp "/Applications/Oxygen XML Editor/lib/saxon9ee.jar" net.sf.saxon.Transform "-s:/Users/admin/Library/Application Support/Enfocus/Switch Server/backing/BEconvertwrkflw/automanaged/Folder 77/_0B800_order_041218-001[1].xml" "-o:/Users/admin/Library/Application Support/Enfocus/Switch Server/temp/87/ScriptElement/1660/7/order_041218-001[1].xml/order_041218-001[1].xml" -xsltversion:2.0 "-xsl:/Users/admin/Documents/Switch_Scripts/RemoveCDATA_v2.xsl"

Re: XSLT help

Posted: Thu Apr 19, 2018 11:03 am
by Padawan
When I test it the configurator it also uses -xsltversion:2.0 and that works for me. But I use a standalone Saxon instead of the one in inside doxygen. Can you try that as well? You can download it here:
https://www.saxonica.com/download/java.xml

After installing you can point the configurator to the new Saxon by right clicking the Saxon configurator in the flow elements pane, choosing "Set path to application" and pointing to the jar file you downloaded.

Re: XSLT help

Posted: Thu Apr 19, 2018 3:16 pm
by actionHero
Thank you for the tips. I followed your suggestion and get the same result.

What version of Saxon are you using?