Reputation: 11
I started learning Linux couple of days ago and currently I'm stuck at XSLT. Sorry if it's a stupid question or already answered elsewhere, I'm quite new here.
My XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<lac xmlns:t="http://smth.de">
<header>
<order id="20210323346730329408"/>
<adress id="IZ0009"/>
</header>
<items>
<item id="1"><material><code>IS-0001-BT-1</code><lotcode/></material><qty>10,000000</qty><expiry/></item>
<item id="2"><material><code>IS-0001-BT-2</code><lotcode/></material><qty>20,000000</qty><expiry/></item>
<item id="3"><material><code>IS-0001-AZ-1</code><lotcode/></material><qty>30,000000</qty><expiry/></item>
<item id="4"><material><code>IS-0001-AZ-2</code><lotcode/></material><qty>40,000000</qty><expiry/></item>
</items>
</lac>
I want to get this output:
Order ID,Adress ID,Item ID,MaterialCode,MaterialLotCode,MaterialQty,Expiry
20210323346730329408,IZ0009,1,IS-0001-BT-1,,10,000000,
20210323346730329408,IZ0009,2,IS-0001-BT-2,,20,000000,
20210323346730329408,IZ0009,3,IS-0001-AZ-1,,30,000000,
20210323346730329408,IZ0009,4,IS-0001-AZ-2,,40,000000,
This is what I got sofar, Your help is very welcome:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:text>Order ID,Adress ID,Item ID,MaterialCode,MaterialLotCode,MaterialQty,Expiry
</xsl:text>
<xsl:apply-templates mode="runHeader"/>
<xsl:apply-templates mode="runItems"/>
</xsl:template>
<xsl:template match="header" mode="runHeader">
<xsl:apply-templates mode="runOrder"/>
<xsl:apply-templates mode="runAdress"/>
</xsl:template>
<xsl:template match="order" mode="runOrder">
<xsl:value-of select="./@id"/>
<xsl:text>,</xsl:text>
</xsl:template>
<xsl:template match="adress" mode="runAdress">
<xsl:value-of select="./@id"/>
<xsl:text>,</xsl:text>
</xsl:template>
<xsl:template match="items" mode="runItems">
<xsl:for-each select="//item">
<xsl:value-of select="./@id"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="./material"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="./lotcode"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="./qty"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="./expiry"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Many thanks in advance.
Upvotes: 1
Views: 85
Reputation: 117100
I would suggest a different approach:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/lac">
<!-- header row -->
<xsl:text>Order ID,Adress ID,Item ID,MaterialCode,MaterialLotCode,MaterialQty,Expiry </xsl:text>
<!-- common data -->
<xsl:variable name="common">
<xsl:value-of select="header/order/@id"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="header/adress/@id"/>
<xsl:text>,</xsl:text>
</xsl:variable>
<!-- data rows -->
<xsl:for-each select="items/item">
<xsl:copy-of select="$common"/>
<xsl:value-of select="@id"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="material/code"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="material/lotcode"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="qty"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="expiry"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Note that this assumes that each item
has at most one material
(your XML structure allows for more).
--
P.S. That's not how you spell address.
Upvotes: 1