I have this XML file, where I have these nodes:
<Rows>
<Row type="Comment">
<Amount>0.00</Amount>
</Row>
<Row type="Spec">
<Amount>10.00</Amount>
</Row>
<Row type="Spec">
<Amount>10.00</Amount>
</Row>
<Row type="Spec">
<Amount>10.00</Amount>
</Row>
<Row type="Comment">
<Amount>0.00</Amount>
</Row>
<Row type="Spec">
<Amount>20.00</Amount>
</Row>
<Row type="Spec">
<Amount>10.00</Amount>
</Row>
<Row type="Spec">
<Amount>20.00</Amount>
</Row>
</Rows>
The result should be:
COMMENT: 30
COMMENT: 50
These Spec rows will always come after Comment rows. I need to do the sum of those Spec rows which are coming after Comment rows.
I tried to use Preceeding and Following functions in XSLT 1.0 but it is not working:
<xsl:value-of select="sum(../Row[#type='Spec']/Amount][following-sibling::row[1][#type='comment']])"/>
Can someone please help?
I would suggest you try it this way:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="spec" match="Row[#type='Spec']" use="generate-id(preceding-sibling::Row[#type='Comment'][1])" />
<xsl:template match="Rows">
<xsl:for-each select="Row[#type='Comment']">
<xsl:text>COMMENT: </xsl:text>
<xsl:value-of select="sum(key('spec', generate-id())/Amount)"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Related
I have an XML, i am trying to do kind of group by with XLST 1.0.
Input XMl:
<Rowset>
<Row>
<col1>7:00</col1>
<name>Shell Test</name>
<passCount>1</passCount>
<failCount>0</failCount>
</Row>
<Row>
<col1>7:00</col1>
<name>Stroke Test</name>
<passCount>1</passCount>
<failCount>1</failCount>
</Row>
<Row>
<col1>7:00</col1>
<name>Shutoff Test</name>
<passCount>0</passCount>
<failCount>1</failCount>
</Row>
<Row>
<col1>8:00</col1>
<name>Shell Test</name>
<passCount>0</passCount>
<failCount>0</failCount>
</Row>
<Row>
<col1>8:00</col1>
<name>Stroke Test</name>
<passCount>0</passCount>
<failCount>0</failCount>
</Row>
<Row>
<col1>8:00</col1>
<name>Shutoff Test</name>
<passCount>0</passCount>
<failCount>0</failCount>
</Row>
<Row>
<col1>9:00</col1>
<name>Shell Test</name>
<passCount>0</passCount>
<failCount>0</failCount>
</Row>
<Row>
<col1>9:00</col1>
<name>Stroke Test</name>
<passCount>0</passCount>
<failCount>0</failCount>
</Row>
<Row>
<col1>9:00</col1>
<name>Shutoff Test</name>
<passCount>0</passCount>
<failCount>0</failCount>
</Row>
</Rowset>
outPutXMl:
<?xml version="1.0" encoding="UTF-8"?>
<Row>
<element>
<TestName>Shell Test</TestName>
</element>
<element>
<TestName>Stroke Test</TestName>
</element>
<element>
<TestName>Shutoff Test</TestName>
</element>
</Row>
<Row>
<element>
<Time>7:00</Time>
<Pass>1</Pass>
<Fail>0</Fail>
<Pass>1</Pass>
<Fail>1</Fail>
<Pass>0</Pass>
<Fail>1</Fail>
</element>
<element>
<Time>8:00</Time>
<Pass>0</Pass>
<Fail>0</Fail>
<Pass>0</Pass>
<Fail>0</Fail>
<Pass>0</Pass>
<Fail>0</Fail>
</element>
<element>
<Time>9:00</Time>
<Pass>0</Pass>
<Fail>0</Fail>
<Pass>0</Pass>
<Fail>0</Fail>
<Pass>0</Pass>
<Fail>0</Fail>
</element>
</Row>
i am facing problem in extracting all the values from group in second for-each-group
my xslt 1.0 is as below:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="col1name" match="Row" use="name" />
<xsl:key name="time" match="Row" use="col1" />
<xsl:template match="/Rowsets/Rowset">
<Row>
<xsl:for-each select="Row[generate-id() = generate-id(key('col1name', name)[1])]">
<TestName><xsl:value-of select="name"/></TestName>
</xsl:for-each>
</Row>
<xsl:for-each select="Row">
<Time><xsl:value-of select="col1"/></Time>
<xsl:apply-templates select="/Rowsets/Rowset"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="/Rowsets/Rowset">
<xsl:for-each select="Row[generate-id() = generate-id(key('time', col1)[*])]">
<Pass><xsl:value-of select="passCount"/></Pass>
<Fail><xsl:value-of select="failCount"/></Fail>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
with XSLT 2.0 i could achieve this, but as per my requirement my application only supports XSLT 1.0
XSLT 2.0 Code:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Rowsets/Rowset">
<Row>
<xsl:for-each-group select="Row" group-by="name">
<element>
<TestName>
<xsl:value-of select="name"/>
</TestName>
</element>
</xsl:for-each-group>
</Row>
<Row>
<xsl:for-each-group select="Row" group-by="col1">
<element>
<Time>
<xsl:value-of select="col1"/>
</Time>
<xsl:for-each select="current-group()">
<Pass>
<xsl:value-of select="passCount"/>
</Pass>
<Fail>
<xsl:value-of select="failCount"/>
</Fail>
</xsl:for-each>
</element>
</xsl:for-each-group>
</Row>
</xsl:template>
</xsl:stylesheet>
Can someone please help in replicating the output with XSLT 1.0
Use the two keys for Muenchian grouping:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:key name="by-name" match="Row" use="name"/>
<xsl:key name="by-col1" match="Row" use="col1"/>
<xsl:template match="/Rowsets/Rowset">
<Row>
<xsl:for-each select="Row[generate-id() = generate-id(key('by-name', name)[1])]">
<element>
<TestName>
<xsl:value-of select="name"/>
</TestName>
</element>
</xsl:for-each>
</Row>
<Row>
<xsl:for-each select="Row[generate-id() = generate-id(key('by-col1', col1)[1])]">
<element>
<Time>
<xsl:value-of select="col1"/>
</Time>
<xsl:for-each select="key('by-col1', col1)">
<Pass>
<xsl:value-of select="passCount"/>
</Pass>
<Fail>
<xsl:value-of select="failCount"/>
</Fail>
</xsl:for-each>
</element>
</xsl:for-each>
</Row>
</xsl:template>
</xsl:stylesheet>
I'm trying to group the input below by the destination and assortment values using muenchian-grouping which is new for me so I'm not sure how to do it properly. The input files will be much larger than this so performance is important.
<?xml version="1.0"?>
<ns0:Data xmlns:ns0="http://BizTalk_Projects.input">
<transports>
<destination>destination 1</destination>
<assortment>Volvo_GA961</assortment>
<quantity>10</quantity>
</transports>
<transports>
<destination>destination 1</destination>
<assortment>Volvo_GA961</assortment>
<quantity>15</quantity>
</transports>
<transports>
<destination>destination 1</destination>
<assortment>Volvo_GA969</assortment>
<quantity>15</quantity>
</transports>
<transports>
<destination>destination 1</destination>
<assortment>Volvo_GA972</assortment>
<quantity>5</quantity>
</transports>
<transports>
<destination>destination 1</destination>
<assortment>Volvo_SA980</assortment>
<quantity>20</quantity>
</transports>
<transports>
<destination>destination 2</destination>
<assortment>Volvo_GA960</assortment>
<quantity>10</quantity>
</transports>
<transports>
<destination>destination 1</destination>
<assortment>Nissan_GA963</assortment>
<quantity>5</quantity>
</transports>
<transports>
<destination>destination 1</destination>
<assortment>Nissan_GA963</assortment>
<quantity>5</quantity>
</transports>
</ns0:Data>
Expected output:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:Destinations xmlns:ns0="http://BizTalk_Projects.output">
<Destination>
<name>destination 1</name>
<assortment>
<name>Volvo_GA</name>
<row>
<type>sumPerAssortment</type>
<id>961</id>
<totalQuantity>25</totalQuantity>
<region>1</region>
</row>
<row>
<type>sumPerAssortment</type>
<id>969</id>
<totalQuantity>15</totalQuantity>
<region>1</region>
</row>
<row>
<type>sumPerAssortment</type>
<id>972</id>
<totalQuantity>5</totalQuantity>
<region>2</region>
</row>
<row>
<type>sumPerRegion</type>
<id />
<totalQuantity>40</totalQuantity>
<region>1</region>
</row>
<row>
<type>sumPerRegion</type>
<id />
<totalQuantity>5</totalQuantity>
<region>2</region>
</row>
<row>
<type>totalSum</type>
<id />
<totalQuantity>45</totalQuantity>
<region />
</row>
</assortment>
<assortment>
<name>Volvo_SA</name>
<row>
<type>sumPerAssortment</type>
<id>980</id>
<totalQuantity>20</totalQuantity>
<region>3</region>
</row>
<row>
<type>sumPerRegion</type>
<id />
<totalQuantity>20</totalQuantity>
<region>3</region>
</row>
<row>
<type>totalSum</type>
<id />
<totalQuantity>20</totalQuantity>
<region />
</row>
</assortment>
<assortment>
<name>Nissan_GA</name>
<row>
<type>sumPerAssortment</type>
<id>963</id>
<totalQuantity>10</totalQuantity>
<region>1</region>
</row>
<row>
<type>sumPerRegion</type>
<id />
<totalQuantity>10</totalQuantity>
<region>1</region>
</row>
<row>
<type>totalSum</type>
<id />
<totalQuantity>10</totalQuantity>
<region />
</row>
</assortment>
</Destination>
<Destination>
<name>destination 2</name>
<assortment>
<name>Volvo_GA</name>
<row>
<type>sumPerAssortment</type>
<id>960</id>
<totalQuantity>10</totalQuantity>
<region>1</region>
</row>
<row>
<type>sumPerRegion</type>
<id />
<totalQuantity>10</totalQuantity>
<region>1</region>
</row>
<row>
<type>totalSum</type>
<id />
<totalQuantity>10</totalQuantity>
<region />
</row>
</assortment>
</Destination>
</ns0:Destinations>
Note:
assortment number starting with 96 = region 1
assortment number starting with 97 = region 2
assortment number starting with 98 = region 3
Start of my XSLT:
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0"
version="1.0"
xmlns:s0="http://BizTalk_Projects.input"
xmlns:ns0="http://BizTalk_Projects.output">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:key name="destinationKey" match="transports" use="destination"/>
<xsl:template match="/">
<xsl:apply-templates select="/s0:Data" />
</xsl:template>
<xsl:template match="/s0:Data">
<ns0:Destinations>
<xsl:for-each select="transports[count(. | key('destinationKey',destination)[1]) = 1]">
<Destination>
<name>
<xsl:value-of select="destination/text()" />
</name>
<xsl:for-each select="key('destinationKey',destination)">
<assortment>
<name>
<xsl:value-of select="substring(assortment/text(),1,string-length(assortment)-3)" />
</name>
</assortment>
</xsl:for-each>
</Destination>
</xsl:for-each>
</ns0:Destinations>
</xsl:template>
</xsl:stylesheet>
With this code, I'm getting this output (duplicate rows, but correct assortments for each destination);
<ns0:Destinations xmlns:ns0="http://BizTalk_Projects.output">
<Destination>
<name>destination 1</name>
<assortment>
<name>Volvo_GA</name>
</assortment>
<assortment>
<name>Volvo_GA</name>
</assortment>
<assortment>
<name>Volvo_GA</name>
</assortment>
<assortment>
<name>Volvo_GA</name>
</assortment>
<assortment>
<name>Volvo_SA</name>
</assortment>
<assortment>
<name>Nissan_GA</name>
</assortment>
<assortment>
<name>Nissan_GA</name>
</assortment>
</Destination>
<Destination>
<name>destination 2</name>
<assortment>
<name>Volvo_GA</name>
</assortment>
</Destination>
</ns0:Destinations>
Any suggestions on how I can solve this? Help is very appreciated!
It's difficult to see how exactly the output relates to the input. Try this as your starting point:
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:key name="transports-by-destination" match="transports" use="destination" />
<xsl:key name="transports-by-assortment" match="transports" use="concat(destination, '|', assortment)" />
<xsl:template match="/*">
<xsl:copy>
<!-- for each unique destination -->
<xsl:for-each select="transports[count(. | key('transports-by-destination', destination)[1]) = 1]">
<Destination>
<name>
<xsl:value-of select="destination"/>
</name>
<xsl:variable name="group" select="key('transports-by-destination', destination)" />
<!-- for each unique assortment in this destination -->
<xsl:for-each select="$group[count(. | key('transports-by-assortment', concat(destination, '|', assortment))[1]) = 1]">
<assortment>
<name>
<xsl:value-of select="assortment"/>
</name>
<!-- process this subgroup -->
<xsl:for-each select="key('transports-by-assortment', concat(destination, '|', assortment))" >
<row>
<!-- not sure what goes in here -->
<totalQuantity>
<xsl:value-of select="quantity"/>
</totalQuantity>
</row>
</xsl:for-each>
</assortment>
</xsl:for-each>
</Destination>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
I am trying to edit the first instance of an empty node(Status) in the following xml :
<?xml version='1.0' encoding='windows-1252'?>
<root>
<row>
<flowname>1</flowname>
<path>#[payload]</path>
<id>3</id>
<setMessage>4</setMessage>
<MockOne>5</MockOne>
<MockTwo>6</MockTwo>
<MockThree>7</MockThree>
<Assert></Assert>
<status>12</status>
</row>
<row>
<flowname>2</flowname>
<path>4</path>
<id>5</id>
<setMessage>6</setMessage>
<MockOne>7</MockOne>
<MockTwo>8</MockTwo>
<MockThree></MockThree>
<Assert></Assert>
<status></status>
</row>
<row>
<flowname>3</flowname>
<path>5</path>
<id>6</id>
<setMessage>7</setMessage>
<MockOne>8</MockOne>
<MockTwo>9</MockTwo>
<MockThree></MockThree>
<Assert>3</Assert>
<status></status>
</row>
</root>
What I want to achieve is for the xslt to find the first instance of the tag which is empty and edit it to say 123. I tried using the following XSLT, but it seems to be replacing every Empty Status tag and I need it only to do the first instance. Kindly suggest on what has to be changed
The XSLT as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="row/status[1][not(text())][1]">
<status>123</status>
</xsl:template>
</xsl:stylesheet>
The output right now is as follows( Every empty Status tag is replaced instead of the first instance of an empty one)
<root>
<row>
<flowname>1</flowname>
<path>#[payload]</path>
<id>3</id>
<setmessage>4</setmessage>
<mockone>5</mockone>
<mocktwo>6</mocktwo>
<mockthree>7</mockthree>
<assert></assert>
<status>12</status>
</row>
<row>
<flowname>2</flowname>
<path>4</path>
<id>5</id>
<setmessage>6</setmessage>
<mockone>7</mockone>
<mocktwo>8</mocktwo>
<mockthree></mockthree>
<assert></assert>
<status>123</status>
</row>
<row>
<flowname>3</flowname>
<path>5</path>
<id>6</id>
<setmessage>7</setmessage>
<mockone>8</mockone>
<mocktwo>9</mocktwo>
<mockthree></mockthree>
<assert>3</assert>
<status>123</status>
</row>
</root>
Your Xpath expression is saying to update all row/status which is empty.
You need to change like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="row[not(preceding-sibling::row[not(normalize-space(status))])]/status[1][not(text())][1]">
<status>123</status>
</xsl:template>
</xsl:stylesheet>
I am trying to filter an xml file in a .Net application I am developing. Some sample xml below, obviously not the proper xml, but near enough :-)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Row A1="1" A2="AMS">
<Name>Ashley</Name>
<Team>Team B</Team>
<Date>3/25/2012</Date>
<Value>511681.15</Value>
</Row>
<Row A1="2" A2="AMS">
<Name>Kylie</Name>
<Team>Team A</Team>
<Date>9/28/2010</Date>
<Value>408438.47</Value>
</Row>
<Row A1="3" A2="AMS">
<Name>Gianna</Name>
<Team>Team B</Team>
<Date>40004</Date>
<Value>109709.22</Value>
</Row>
<Row A1="4" A2="AMS">
<Name>Chase</Name>
<Team>Team F</Team>
<Date>40152</Date>
<Value>279018.79</Value>
</Row>
The stylesheet has a param that is set by XsltArgumentList in the application. The param is passed into the stylesheet, but does not filter the xml. I have tried using the ms node-set and exsl node-set but only get the top level root returned. Stylesheet below:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<xsl:decimal-format name="NN" NaN="0" />
<xsl:param name="Filter" />
<xsl:template match="/">
<Root>
<xsl:for-each select="exsl:node-set($Filter)">
<Row>
<xsl:attribute name="A1">
<xsl:value-of select="#A1" />
</xsl:attribute>
<xsl:attribute name="A2">
<xsl:value-of select="#A2" />
</xsl:attribute>
<Team>
<xsl:value-of select="Team"/>
</Team>
</Row>
</xsl:for-each>
</Root>
</xsl:template>
The filter i am trying to pass could be using any of the combination of the xml elements. The filter is am currently attempting is below
<xsl:param name="Filter" select="//Row[Team='Team A']" />
But this is just returns
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Row A1="" A2="">
<Team></Team>
</Row>
</Root>
Any help or pointers would be appreciated!
Thanks
This will not woke like you tried it, because you can't have a xpath expression in an XLST parameter or variable. You can use variable or parameter in please of const values.
Therefore you can use something like
<xsl:param name="teamFilter" select="'Team A'" />
...
<xsl:for-each select="//Row[Team='$teamFilter']">
Or if you have to filter for different nodes you may try:
<xsl:param name="filterValue" select="'Team A'" />
<xsl:param name="filterNode" select="'Team'" />
...
<xsl:for-each select="//Row[*[name()= $filterNode and . =$filterValue]]">
Other alternatives would be:
Patch the XSLT before loading it
Use xpath iterator with XPathExpression from .NET.
The xslt I'm currently using generates all the tags on the root.
I need to get the <row> sets and <config> set.
Source Xml:
<root>
<postdate>2011-03-30</postdate>
<location>84</location>
<meal>07:36</meal>
<config>
<postdate>2011-03-30</postdate>
<location>84</location>
<meal>07:36</meal>
<checknumber>91339082011-03-30T07:36:12</checknumber>
</config>
<items>
<row>
<descriptor>7297364</descriptor>
<qty>1</qty>
<price>33</price>
<value>33</value>
<recordtype>1</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
<row>
<descriptor>7794473</descriptor>
<qty>1</qty>
<price>60</price>
<value>60</value>
<recordtype>1</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
</items>
<tenders>
<row>
<id>13</id>
<value>117.99</value>
<recordtype>2</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
</tenders>
<taxes>
<row>
<id>2</id>
<value>8.25</value>
<recordtype>3</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
</taxes>
</root>
Attempted Xslt:
<xsl:stylesheet version="1.0" exclude-result-prefixes="msxsl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="row/*">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Desired Output:
<root>
<config>
<postdate>2011-03-30</postdate>
<location>84</location>
<meal>07:36</meal>
<checknumber>91339082011-03-30T07:36:12</checknumber>
</config>
<row>
<descriptor>7297364</descriptor>
<qty>1</qty>
<price>33</price>
<value>33</value>
<recordtype>1</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
<row>
<descriptor>7794473</descriptor>
<qty>1</qty>
<price>60</price>
<value>60</value>
<recordtype>1</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
<row>
<id>13</id>
<value>117.99</value>
<recordtype>2</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
<row>
<id>2</id>
<value>8.25</value>
<recordtype>3</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
</root>
This short and simple transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"node()[not(self::root or ancestor-or-self::config or ancestor-or-self::row)]">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<root>
<postdate>2011-03-30</postdate>
<location>84</location>
<meal>07:36</meal>
<config>
<postdate>2011-03-30</postdate>
<location>84</location>
<meal>07:36</meal>
<checknumber>91339082011-03-30T07:36:12</checknumber>
</config>
<items>
<row>
<descriptor>7297364</descriptor>
<qty>1</qty>
<price>33</price>
<value>33</value>
<recordtype>1</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
<row>
<descriptor>7794473</descriptor>
<qty>1</qty>
<price>60</price>
<value>60</value>
<recordtype>1</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
</items>
<tenders>
<row>
<id>13</id>
<value>117.99</value>
<recordtype>2</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
</tenders>
<taxes>
<row>
<id>2</id>
<value>8.25</value>
<recordtype>3</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
</taxes>
</root>
produces the wanted, correct result:
<root>
<config>
<postdate>2011-03-30</postdate>
<location>84</location>
<meal>07:36</meal>
<checknumber>91339082011-03-30T07:36:12</checknumber>
</config>
<row>
<descriptor>7297364</descriptor>
<qty>1</qty>
<price>33</price>
<value>33</value>
<recordtype>1</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
<row>
<descriptor>7794473</descriptor>
<qty>1</qty>
<price>60</price>
<value>60</value>
<recordtype>1</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
<row>
<id>13</id>
<value>117.99</value>
<recordtype>2</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
<row>
<id>2</id>
<value>8.25</value>
<recordtype>3</recordtype>
<postdate>2011-03-30</postdate>
<location>84</location>
</row>
</root>
Explanation:
Using and overriding the identity rule.
Proper use of the ancestor-or-self:: axis.
I figured it. This xslt works for me.
<xsl:stylesheet version="1.0" exclude-result-prefixes="msxsl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<root>
<xsl:for-each select="//row">
<row>
<xsl:apply-templates/>
</row>
</xsl:for-each>
<xsl:for-each select="//config">
<config>
<xsl:apply-templates/>
</config>
</xsl:for-each>
</root>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>