Reputation: 15
I'm struggling with an xslt issue where I need to copy everything under a specific element, but I also need to change the value of one of the attributes.
Here is my XML:
<?xml version="1.0" encoding="UTF-8"?>
<message>
<datetime datum="20190318" time="154933"/>
<information environment="A" formula="AA" database_action="I"/>
<identification versionnumber="1" publication_type="MESSAGE_NAME"/>
<content>
<PickWave>
<Pick pickID="1" groupID="11802182" groupType="orderPick" eachQuantity="1" sourceLocation="P5F.021.01-004" destinationLocation="E1A">
<Container containerID="11802182">
<ContainerType>CRATE</ContainerType>
</Container>
<Product productID="593000" description="593000-DESCRIPTION" unitOfMeasure="Box" weightUnitOfMeasure="g" dimensionUnitOfMeasure="mm" length="230" width="115,5" height="95" weight="312,1">
<Identifiers>
<Identifier label="barcode">
<AllowedValues>8713776016527</AllowedValues>
</Identifier>
</Identifiers>
</Product>
<Data>
<containerType>CRATE</containerType>
</Data>
</Pick>
<Pick pickID="2" groupID="11802182" groupType="orderPick" eachQuantity="1" sourceLocation="P5F.022.01-001" destinationLocation="E1A">
<Container containerID="11802182">
<ContainerType>CRATE</ContainerType>
</Container>
<Product productID="600318" description="600318-DESCRIPTION" unitOfMeasure="Bag" weightUnitOfMeasure="g" dimensionUnitOfMeasure="mm" length="160" width="160" height="230" weight="26,5">
<Identifiers>
<Identifier label="barcode">
<AllowedValues>8711247936732</AllowedValues>
</Identifier>
</Identifiers>
</Product>
<Data>
<containerType>CRATE</containerType>
</Data>
</Pick>
</PickWave>
</content>
<error exitcode="" message=""/>
</message>
And here is my XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy copy-namespaces="no">
<xsl:message>
<xsl:value-of select="name(.)"/>
</xsl:message>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- When attribute matches @weight, @lenght, @width or @height, replace comma (EU) with dots (US) as decimal seperator -->
<xsl:template match="*:Product/@weight | *:Product/@length | *:Product/@width | *:Product/@height">
<xsl:variable name="vAttr" select="name(.)"/>
<xsl:attribute name="{$vAttr}" select="translate(.,',','.')"/>
</xsl:template>
</xsl:stylesheet>
I understand that my first template matches every element/attribute and thus creates the <message>
until <content>
elements, but how do I get it to match every element and attribute from the PickWave element en copy all those elements?
And this would be my desired output:
<?xml version="1.0" encoding="UTF-8"?>
<PickWave>
<Pick pickID="1" groupID="11802182" groupType="orderPick" eachQuantity="1" sourceLocation="P5F.021.01-004" destinationLocation="E1A">
<Container containerID="11802182">
<ContainerType>CRATE</ContainerType>
</Container>
<Product productID="593000" description="593000-DESCRIPTION" unitOfMeasure="Box" weightUnitOfMeasure="g" dimensionUnitOfMeasure="mm" length="230" width="115.5" height="95" weight="312.1">
<Identifiers>
<Identifier label="barcode">
<AllowedValues>8713776016527</AllowedValues>
</Identifier>
</Identifiers>
</Product>
<Data>
<containerType>CRATE</containerType>
</Data>
</Pick>
<Pick pickID="2" groupID="11802182" groupType="orderPick" eachQuantity="1" sourceLocation="P5F.022.01-001" destinationLocation="E1A">
<Container containerID="11802182">
<ContainerType>CRATE</ContainerType>
</Container>
<Product productID="600318" description="600318-DESCRIPTION" unitOfMeasure="Bag" weightUnitOfMeasure="g" dimensionUnitOfMeasure="mm" length="160" width="160" height="230" weight="26.5">
<Identifiers>
<Identifier label="barcode">
<AllowedValues>8711247936732</AllowedValues>
</Identifier>
</Identifiers>
</Product>
<Data>
<containerType>CRATE</containerType>
</Data>
</Pick>
</PickWave>
Upvotes: 1
Views: 1243
Reputation: 1882
but how do I get it to match every element and attribute from the PickWave
If I'm getting you right, you want to change those attributes in any descendant element of PickWave
element. So you need:
<xsl:template match="*:PickWave//@weight
|*:PickWave//@lenght
|*:PickWave//@width
|*:PickWave//@height">
<xsl:attribute name="{name()}" select="translate(.,',','.')"/>
</xsl:template>
Or if you want a pattern more in the XSLT 2.0 style
<xsl:template match="*:PickWave//@*[
some $a in ../(@weight|@lenght|@width|@height)
satisfies $a is .
]">
<xsl:attribute name="{name()}" select="translate(.,',','.')"/>
</xsl:template>
Upvotes: 1
Reputation: 70618
If you only want the PickWave
elements in your output, one solution is to simply have a template matching the document node, and then select only the elements you wish to copy....
Try adding this template to your existing XSLT
<xsl:template match="/">
<xsl:apply-templates select="message/content/PickWave" />
</xsl:template>
Upvotes: 1