I'm quite new to XSLT and have no clue how to find a solution for my desired transformation. We receive a SOAP request and need to check if a certain tag (Steps) exists. If not present I want to add it to the SOAP message.
We are running the interface on Azure API Management which allows XSLT only in version 1.0.
XML example
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ProductionToSupply xmlns="http://somenamespace.com">
<ProductionDataList>
<ProductionData>
<Material_Number>5</Material_Number>
<Doc_Number>1234</Doc_Number>
<Description>abcde</Description>
</ProductionData>
</ProductionDataList>
</ProductionToSupply>
</soap:Body>
</soap:Envelope>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://somenamespace.com" exclude-result-prefixes="ns1">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="soap:Envelope/soap:Body/ns1:ProductionToSupply/ns1:ProductionDataList/ns1:ProductionData/ns1:Doc_Number">
<xsl:if test="not(soap:Envelope/soap:Body/ns1:ProductionToSupply/ns1:ProductionDataList/ns1:ProductionData/ns1:Steps)">
<Steps xmlns="http://somenamespace.com">NA</Steps>
</xsl:if>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
desired output
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ProductionToSupply xmlns="http://somenamespace.com">
<ProductionDataList>
<ProductionData>
<Material_Number>5</Material_Number>
<Doc_Number>1234</Doc_Number>
<Description>abcde</Description>
<Steps>NA</Steps>
</ProductionData>
</ProductionDataList>
</ProductionToSupply>
</soap:Body>
</soap:Envelope>
The expected result would be to only add the tag "Steps" if it is not present in group "ProductionData", but I don't know how to set the appropriate match pattern.
Thanks in advance for your help tim
If you want to match the group ProductionData
only if it doesn't have a Steps
element, the template match would be this
<xsl:template match="ns1:ProductionData[not(ns1:Steps)]">
You could then copy the ProductionData
element and its child node, and slip in the Steps
element at the same time
Try this XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://somenamespace.com" exclude-result-prefixes="ns1">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns1:ProductionData[not(ns1:Steps)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<Steps xmlns="http://somenamespace.com">NA</Steps>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
This would add the Steps
as the last child. If you wanted it immediately after Doc_Number
, replace the template with this
<xsl:template match="ns1:ProductionData[not(ns1:Steps)]/ns1:Doc_Number">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<Steps xmlns="http://somenamespace.com">NA</Steps>
</xsl:template>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.