Reputation: 734
I have the following xml and xsl files and I am trying to sort the CARTONDETAIL
nodes, but leave the rest of the document as the original.
So far, the top part of my document gets copied over, everything before CARTONDETAIL
. After that I just get a lot of empty <CARTONDETAIL>
tags, like I am creating an endless loop, because the document never puts the closing brackets at the end nor the other HEADER
instance. In the input file I have two instances of the HEADER
tree, but I don't see any traces of the second one in my output file.
I am using saxon to parse the documents.
Any help is greatly appreciated.. Thanks all!
XML:
<?xml version="1.0" encoding="UTF-8"?>
<TRUCKSHIPUPLOAD>
<HEADER>
<WH>WH1</WH>
<OWN>FakeOwner</OWN>
<ORD>1035710</ORD>
<RELEASE_NUM>1</RELEASE_NUM>
<ORDER_LINE/>
<TRUCK>0222001406</TRUCK>
<ORDERING>1</ORDERING>
<TRAILER_ID/>
<WAREHOUSE_ID>UDS01</WAREHOUSE_ID>
<OWNER_ID>CAYRE</OWNER_ID>
<IF_SEQ_NUM>222001406</IF_SEQ_NUM>
<IF_STATUS/>
<IF_ERROR_MSG/>
<ORDER_ID>1035710</ORDER_ID>
<STAT_DATE/>
.........
<CARTON>
<WH>WH1</WH>
<OWN>FakeOwner</OWN>
<ORD>1035710</ORD>
<RELEASE_NUM>1</RELEASE_NUM>
<ORDER_LINE/>
<TRUCK>0222001406</TRUCK>
<ORDERING>4</ORDERING>
<TRAILER_ID/>
....
<CARTONDETAIL>
<WH>WH1</WH>
<OWN>FakeOwner</OWN>
<ORD>1035710</ORD>
<RELEASE_NUM>1</RELEASE_NUM>
<ORDER_LINE>4</ORDER_LINE>
<TRUCK>0222001406</TRUCK>
<TRAILER_ID/>
<WAREHOUSE_ID>WH1</WAREHOUSE_ID>
<OWNER_ID>FakeOwner</OWNER_ID>
<IF_SEQ_NUM/>
<IF_STATUS/>
<IF_ERROR_MSG/>
<ORDER_ID>1035710</ORDER_ID>
<STAT_DATE/>
...
</CARTONDETAIL>
<CARTONDETAIL>
<WH>WH1</WH>
<OWN>FakeOwner</OWN>
<ORD>1035710</ORD>
<RELEASE_NUM>1</RELEASE_NUM>
<ORDER_LINE>8</ORDER_LINE>
<TRUCK>0222001406</TRUCK>
<TRAILER_ID/>
<WAREHOUSE_ID>WH1</WAREHOUSE_ID>
<OWNER_ID>FakeOwner</OWNER_ID>
<IF_SEQ_NUM/>
<IF_STATUS/>
<IF_ERROR_MSG/>
<ORDER_ID>1035710</ORDER_ID>
<STAT_DATE/>
...
</CARTONDETAIL>
<CARTONDETAIL>
<WH>WH1</WH>
<OWN>FakeOwner</OWN>
<ORD>1035710</ORD>
<RELEASE_NUM>1</RELEASE_NUM>
<ORDER_LINE>2</ORDER_LINE>
<TRUCK>0222001406</TRUCK>
<TRAILER_ID/>
<WAREHOUSE_ID>WH1</WAREHOUSE_ID>
<OWNER_ID>FakeOwner</OWNER_ID>
<IF_SEQ_NUM/>
<IF_STATUS/>
<IF_ERROR_MSG/>
<ORDER_ID>1035710</ORDER_ID>
<STAT_DATE/>
...
</CARTONDETAIL>
</CARTON>
</HEADER>
</TRUCKSHIPUPLOAD>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="CARTONDETAIL">
<xsl:copy>
<xsl:apply-templates select="//CARTONDETAIL">
<xsl:sort select="ORDER_LINE" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 68
Reputation: 437
Copy all nodes and sort CARTONDETAIL with respect to ORDER_LINE, hope that this is what you wanted.
<xsl:output method="xml" indent="yes"/>
<xsl:template match="CARTON">
<xsl:copy>
<xsl:apply-templates select="CARTONDETAIL">
<xsl:sort select="ORDER_LINE" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 117073
First thing: you do have an infinite loop here:
<xsl:template match="CARTONDETAIL">
<xsl:copy>
<xsl:apply-templates select="//CARTONDETAIL">
...
Now, assuming you want to sort the CARTONDETAIL
nodes within their parent CARTON
, try:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CARTON">
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:sort select="ORDER_LINE" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 167691
I think instead of
<xsl:template match="CARTONDETAIL">
<xsl:copy>
<xsl:apply-templates select="//CARTONDETAIL">
<xsl:sort select="ORDER_LINE" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
you want
<xsl:template match="CARTON">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="boolean(self::CARTONDETAIL)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:apply-templates select="current-group()">
<xsl:sort select="ORDER_LINE" data-type="number"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:copy>
</xsl:template>
Upvotes: 3