I'm very much a beginner with xsl transformations
I have some xml that I need to insert an attribute into an element when that attribute doesn't exist..
Using the below xml as an example.
<Order Id="IR1598756" Status="2">
<Details>
<SomeInfo>Sample Data</SomeInfo>
</Details>
<Documents>
<Invoice>
<Date>15-02-2011</Date>
<Time>11:22</Time>
<Employee Id="159">James Morrison</Employee>
</Invoice>
<DeliveryNote>
<Reference>DN1235588</Reference>
<HoldingRef>HR1598785</HoldingRef>
<Date>16-02-2011</Date>
<Time>15:00</Time>
<Employee Id="25">Javi Cortez</Employee>
</DeliveryNote>
</Documents>
</Order>
Desired Output
<Order Id="IR1598756" Status="2">
<Details>
<SomeInfo>Sample Data</SomeInfo>
</Details>
<Documents>
<Invoice Id="DN1235588">
<Date>15-02-2011</Date>
<Time>11:22</Time>
<Employee Id="159">James Morrison</Employee>
</Invoice>
</Documents>
</Order>
The <Invoice>
element can have an Id attribute <Invoice Id="IR1564897">
How can I check the following.
- Check that the attribute exists
- If not then Insert the Value of the
<Refernce>DN1235588</Reference>
as theId
- If there is no
<Reference>
Use the Value of the<HoldingRef>HR1598785</HoldingRef>
I was looking at implementing something like the following
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="//Order"/>
</xsl:template>
<xsl:template match="Order/Documents/Invoice[not(@Id)]">
<xsl:attribute name="Id">
<xsl:value-of select="//Documents/DeliveryNote/Reference"/>
</xsl:attribute>
</xsl:template>
The above is not outputting the full <Invoice>
element.
How can I correct this?
<xsl:if test="Order/Documents/DeliveryNote/Reference">
<xsl:value-of select="//Documents/DeliveryNote/Reference"/>
</xsl:if>
<xsl:if test="Not(Order/Documents/DeliveryNote/Reference)">
<xsl:value-of select="//Documents/DeliveryNote/HoldingRef"/>
</xsl:if>
If either one will always exist will this work to alternate between <Reference>
and <HoldingRef>
?
With the help of Alex: The following has worked for me to replace the attribute
<xsl:template match="Order/Documents/Invoice[not(@Id)]">
<Invoice>
<xsl:attribute name="Id">
<xsl:value-of Select="//Documents/DeliveryNote/Reference"/>
</xsl:attribute>
<xsl:apply-templates select="@* | node()"/>
</Invoice>
</xsl:template>
Give a try:
As for your questions:
See my example.
Either with XPath (as in my example) or with
xsl:choose
.The shortest answer:
What about this?
Use it instead your
<xsl:template match="Order/Documents/Invoice[not(@Id)]">