I got stuck with my code using a lookup XML with an XSLT
my XML is like this:
<?xml version="1.0"?>
<Invoices>
<invoice>
<customer>
<name>Juan tamban</name>
</customer>
<details>
<VAT>0001</VAT>
<items>
<item code="I01" name="Item1" />
<item code="I02" name="Item2" />
</items>
</details>
</invoice>
<invoice>
<customer>
<name>Johny Cash</name>
</customer>
<details>
<VAT>0002</VAT>
<items>
<item code="I03" name="Item3" />
<item code="I04" name="Item4" />
</items>
</details>
</invoice>
</Invoices>
And my current XSLT looks like this:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="lookupdoc" select="document('Lookup.xml')/VATS/VAT"/>
<xsl:key name="VAT-by-id" match="VAT" use="@id"/>
<xsl:template name="getCode">
<xsl:param name="VATNumber" />
<xsl:variable name="VATId" select="$VATNumber/."/>
<xsl:for-each select="$lookupdoc">
<xsl:value-of select="key('VAT-by-id', $VATId/VAT)/code"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="items/item">
<Item>
<ItemCOde>
<xsl:value-of select="@code"/>
</ItemCOde>
<ItemName>
<xsl:value-of select="@name"/>
</ItemName>
</Item>
</xsl:template>
<xsl:template match="invoice">
<xsl:variable name="VAT">
<xsl:call-template name="getCode">
<xsl:with-param name="VATNumber" select="details/VAT" />
</xsl:call-template>
</xsl:variable>
<InvoiceDetails>
<CustomerName>
<xsl:value-of select="customer/name"/>
</CustomerName>
<VATCode>
<xsl:value-of select="$VAT" />
</VATCode>
<xsl:apply-templates select="details/items/item" />
</InvoiceDetails>
</xsl:template>
<xsl:template match="Invoices">
<Invoices>
<xsl:apply-templates select ="invoice"/>
</Invoices>
</xsl:template>
</xsl:stylesheet>
And my lookup XML is this:
<?xml version="1.0" encoding="utf-8"?>
<VATS>
<VAT id="0001" code="0001-000101/08-12-2021"/>
<VAT id="0002" code="0002-000102/09-12-2021"/>
<VAT id="0003" code="0003-000103/10-12-2021"/>
<VAT id="0004" code="0004-000104/11-12-2021"/>
</VATS>
My result is like this, and as you can see the VATCode tag is not filled in:
<?xml version="1.0" encoding="utf-8"?>
<Invoices>
<InvoiceDetails>
<CustomerName>Juan tamban</CustomerName>
<VATCode></VATCode>
<Item>
<ItemCOde>I01</ItemCOde>
<ItemName>Item1</ItemName>
</Item>
<Item>
<ItemCOde>I02</ItemCOde>
<ItemName>Item2</ItemName>
</Item>
</InvoiceDetails>
<InvoiceDetails>
<CustomerName>Johny Cash</CustomerName>
<VATCode></VATCode>
<Item>
<ItemCOde>I03</ItemCOde>
<ItemName>Item3</ItemName>
</Item>
<Item>
<ItemCOde>I04</ItemCOde>
<ItemName>Item4</ItemName>
</Item>
</InvoiceDetails>
</Invoices>
Anyone can let me know what is missing or what is wrong with this code?
Thanks for the help.
CodePudding user response:
Your code will work if you change this:
<xsl:variable name="lookupdoc" select="document('Lookup.xml')/VATS/VAT"/>
to:
<xsl:variable name="lookupdoc" select="document('Lookup.xml')"/>
and this:
<xsl:template name="getCode">
<xsl:param name="VATNumber" />
<xsl:variable name="VATId" select="$VATNumber/."/>
<xsl:for-each select="$lookupdoc">
<xsl:value-of select="key('VAT-by-id', $VATId/VAT)/code"/>
</xsl:for-each>
</xsl:template>
to:
<xsl:template name="getCode">
<xsl:param name="VATNumber" />
<xsl:for-each select="$lookupdoc">
<xsl:value-of select="key('VAT-by-id', $VATNumber)/@code"/>
</xsl:for-each>
</xsl:template>
Of course, you could shorten the whole thing to:
<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:param name="lookupdoc" select="document('Lookup.xml')"/>
<xsl:key name="VAT-by-id" match="VAT" use="@id"/>
<xsl:template match="/Invoices">
<Invoices>
<xsl:apply-templates select="invoice"/>
</Invoices>
</xsl:template>
<xsl:template match="invoice">
<InvoiceDetails>
<CustomerName>
<xsl:value-of select="customer/name"/>
</CustomerName>
<VATCode>
<xsl:variable name="VATNumber" select="details/VAT" />
<xsl:for-each select="$lookupdoc">
<xsl:value-of select="key('VAT-by-id', $VATNumber)/@code"/>
</xsl:for-each>
</VATCode>
<xsl:apply-templates select="details/items/item" />
</InvoiceDetails>
</xsl:template>
<xsl:template match="items/item">
<Item>
<ItemCOde>
<xsl:value-of select="@code"/>
</ItemCOde>
<ItemName>
<xsl:value-of select="@name"/>
</ItemName>
</Item>
</xsl:template>
</xsl:stylesheet>
P.S. I believe your decision to use a key is the correct one.
CodePudding user response:
I think you have shot yourself into the foot trying to use the key, you just want
<xsl:template name="getCode">
<xsl:param name="VATNumber" />
<xsl:for-each select="$lookupdoc">
<xsl:value-of select="key('VAT-by-id', $VATNumber)/@code"/>
</xsl:for-each>
</xsl:template>
I would also change <xsl:variable name="lookupdoc" select="document('Lookup.xml')/VATS/VAT"/>
to <xsl:variable name="lookupdoc" select="document('Lookup.xml')"/>
, as you just want and need the document node for the context switch when using the key so there is no advantage in selecting downwards.