Home > Blockchain >  Transform element to atribute
Transform element to atribute

Time:10-06

I want to set the value of one element in the xml file as an attribute of another element using xslt, and I no idea how it to do. My input xml file:

<?xml version="1.0" encoding="UTF-8"?>
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2021-10-05T00:52:16">
<Invoice>
<ID>123</ID>
<IssueDate>2011-09-22</IssueDate>
<DueDate>2021-09-22</DueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
...
<InvoiceLine>
<ID>2</ID>
<InvoicedQuantity>1.0000</InvoicedQuantity>
<unitCode>kg</unitCode>
<LineExtensionAmount>12.0000</LineExtensionAmount>
<TaxTotal>
<TaxAmount>1.2000</TaxAmount>
<IDfakture>2</IDfakture>
</TaxTotal>
<Item>
<Description>artikal 2</Description>
<Name>2</Name>
</Item>
<Price>
<PriceAmount>15.0000</PriceAmount>
<AllowanceCharge>
<ChargeIndicator>1</ChargeIndicator>
<MultiplierFactorNumeric>20.0000</MultiplierFactorNumeric>
<Amount>3.0000</Amount>
</AllowanceCharge>
</Price>
</InvoiceLine>
</Invoice>
</dataroot>

Im using xslt and want value of the element unitCode to be an attribute of the element
InvoicedQuantity and then to remove element unitCode

Output xml I need:

<?xml version="1.0" encoding="UTF-8"?>
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2021-10-05T00:52:16">
<Invoice>
<ID>123</ID>
<IssueDate>2011-09-22</IssueDate>
<DueDate>2021-09-22</DueDate>
<InvoiceTypeCode>380</InvoiceTypeCode>
...
<InvoiceLine>
<ID>2</ID>
<InvoicedQuantity unitCode="kg">1.0000</InvoicedQuantity>
<LineExtensionAmount>12.0000</LineExtensionAmount>
<TaxTotal>
<TaxAmount>1.2000</TaxAmount>
<IDfakture>2</IDfakture>
</TaxTotal>
<Item>
<Description>artikal 2</Description>
<Name>2</Name>
</Item>
<Price>
<PriceAmount>15.0000</PriceAmount>
<AllowanceCharge>
<ChargeIndicator>1</ChargeIndicator>
<MultiplierFactorNumeric>20.0000</MultiplierFactorNumeric>
<Amount>3.0000</Amount>
</AllowanceCharge>
</Price>
</InvoiceLine>
</Invoice>
</dataroot>

Please help.

CodePudding user response:

You can use these two templates in combination with the identity template (Only XSLT-1.0 is needed):

<xsl:template match="InvoicedQuantity">
  <xsl:copy>
    <xsl:attribute name="unitCode"><xsl:value-of select="following-sibling::unitCode[1]" /></xsl:attribute>
      <xsl:apply-templates select="node()|@*" />
  </xsl:copy>
</xsl:template>

<xsl:template match="unitCode" />

They remove all <unitCode> elements, but if every one is preceeded by an <InvoicedQuantity> element, the code should work as desired. The XSLT-1.0 identity template that copies all unmatched elements is:

<!-- identity template -->
<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*" />
  </xsl:copy>
</xsl:template> 
  • Related