0

For SAP PO I want to suppress creating xml output when one of my nodes has a certain value.

I've checked this link but I still keep getting output in my xml (envelope / parent nodes) iow I don't get it...

My XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ns0="http://schemas.microsoft.com/dynamics/2008/01/documents/Message"
  xmlns:ns1="http://schemas.microsoft.com/dynamics/2008/01/documents/IntertourExtTasks">
     <xsl:output method="xml" indent="yes" />

    <xsl:template match="@*|node()">
    <xsl:choose>
        <xsl:when test="ns1:CustAccount = '13262'">
            
        </xsl:when>
        <xsl:otherwise>
            <!-- ... output ... -->
            <xsl:copy>
                <xsl:apply-templates/>
            </xsl:copy>            
        </xsl:otherwise>
    </xsl:choose>
    
</xsl:template>
</xsl:stylesheet>

SOURCE:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Envelope xmlns:ns0="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
    <ns0:Header>
        <ns0:MessageId>{00000000-0000-0000-0000-000010411998}</ns0:MessageId>
    </ns0:Header>
    <ns0:Body>
        <ns0:MessageParts>
            <ns1:IntertourExtTasks xmlns:ns1="http://schemas.microsoft.com/dynamics/2008/01/documents/IntertourExtTasks">
                <ns1:IntertourExternalTasks class="entity">
                    <ns1:BringGet>Get</ns1:BringGet>
                    <ns1:CustAccount>13262</ns1:CustAccount>
                </ns1:IntertourExternalTasks>
                <ns1:IntertourExternalTasks class="entity">
                    <ns1:BringGet>Get</ns1:BringGet>
                    <ns1:CustAccount>13262</ns1:CustAccount>
                </ns1:IntertourExternalTasks>
            </ns1:IntertourExtTasks>
        </ns0:MessageParts>
    </ns0:Body>
</ns0:Envelope>

Expected result when CustAccount = 13262:

<?xml version="1.0" encoding="UTF-8"?>

Result I get:

<?xml version="1.0" encoding="UTF-8"?><ns0:Envelope xmlns:ns0="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
    <ns0:Header>
        <ns0:MessageId>{00000000-0000-0000-0000-000010411998}</ns0:MessageId>
    </ns0:Header>
    <ns0:Body>
        <ns0:MessageParts>
            <ns1:IntertourExtTasks xmlns:ns1="http://schemas.microsoft.com/dynamics/2008/01/documents/IntertourExtTasks">
                
                
            </ns1:IntertourExtTasks>
        </ns0:MessageParts>
    </ns0:Body>
</ns0:Envelope>

UPDATE: Since I needed a blank output / empty file without an xml declaration I had to use omit-xml-declaration="yes". But I wasn't sure that all of my target systems could deal with xml files without a declaration so I added a conditional xsl:text at the start for 'regular output'. For completeness my xsl:

 <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:ns0="http://schemas.microsoft.com/dynamics/2008/01/documents/Message"
      xmlns:ns1="http://schemas.microsoft.com/dynamics/2008/01/documents/IntertourExtTasks">
         <xsl:output method="xml" indent="no" omit-xml-declaration="yes" />

        <!-- If one of the nodes have a custaccount of 13262 then NO OUTPUT otherwise output XML declaration-->
        <xsl:template match="/">
          <xsl:choose>
            <xsl:when test="/*[.//ns1:CustAccount[. = '13262']]">
            </xsl:when>
            <xsl:otherwise> <xsl:text disable-output-escaping="yes">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
            </xsl:text></xsl:otherwise>
        </xsl:choose>
         <xsl:apply-templates/>
       </xsl:template>
      
        <!-- If one of the nodes have a custaccount of 13262 then NO OUTPUT-->
        <xsl:template match="/*[.//ns1:CustAccount[. = '13262']]"/>
       
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
    </xsl:stylesheet>

Regards, Mike

1 Answer 1

1

I would keep the identiy transformation if that is what you need in general but then block any processing for documents containing that element and value with

  <xsl:template match="/*[.//ns1:CustAccount[. = '13262']]"/>
Sign up to request clarification or add additional context in comments.

7 Comments

As always you're a lifesaver Martin, thank you very much!
One more small question Martin: I want to omit the xml declaration (omit-xml-declaration="yes") . Ik know I can use sth like: <xsl:text disable-output-escaping="yes">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</xsl:text> But how do I implement that to only add one line in combination with suggested solution?
I am not sure I understand what you want to achieve as you say you want to omit the XML declaration and seem to know about <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> but then show code to output one. Perhaps raise a new question where you explain the details.
The goal is to write an empty file when the custaccount is 13262. I've succeeded doing that thanks to you and with the omit statement the output file is empty. Most of the times however there will be output (custaccount != 13262) and in these cases I do need the xml declaration in my output.
I am not sure there is a way in pure XSLT 1, does your XSLT 1.0 processor support exsl:document? Then you might be able to conditionally set up the output with an XML declaration.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.