Mike Dole
Mike Dole

Reputation: 687

XSL filter elements based on node value

I can't seem to figure out how I can succesfully implement this basic xsl. I want to filter out all SalesLines elements in my xml with a SalesOrderStatus value <> SalesOrder (Don't keep Sent / CancelledBySales).

Source XML:

    <?xml version="1.0" encoding="UTF-8"?><Envelope xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
    <Header>
        <MessageId>{9CEDBBC7-5AF3-4A8B-AC68-49F1E0D8402A}</MessageId>
        <SourceEndpoint>hwf</SourceEndpoint>
        <DestinationEndpoint>HWF_ORDRSP</DestinationEndpoint>
        <Action>http://schemas.microsoft.com/dynamics/2008/01/services/SalesSalesOrderService/read</Action>
    </Header>
    <Body>
        <MessageParts>
            <SalesOrder xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">
                <SalesTable class="entity">
                    <CustAccount>00003</CustAccount>
                    <DeliveryDate>2019-10-21</DeliveryDate>
                    <POMOrderId>0002539819</POMOrderId>
                    <PurchOrderFormNum>4500143886</PurchOrderFormNum>
                    <SalesId>QN00000949</SalesId>
                    <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                    <SalesLine class="entity">
                        <ExtLineNum>10</ExtLineNum>
                        <ItemId>08201</ItemId>
                        <SalesId>QN00000949</SalesId>
                        <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                        <SalesQty>1320.00</SalesQty>
                        <SalesUnit>st</SalesUnit>
                        <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
                    </SalesLine>
                    <SalesLine class="entity">
                        <ExtLineNum>20</ExtLineNum>
                        <ItemId>08236</ItemId>
                        <SalesId>QN00000949</SalesId>
                        <SalesOrderStatus>Sent</SalesOrderStatus>
                        <SalesQty>1296.00</SalesQty>
                        <SalesUnit>st</SalesUnit>
                        <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
                    </SalesLine>
                    <SalesLine class="entity">
                        <ExtLineNum>30</ExtLineNum>
                        <ItemId>08238</ItemId>
                        <SalesId>QN00000949</SalesId>
                        <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                        <SalesQty>1296.00</SalesQty>
                        <SalesUnit>st</SalesUnit>
                        <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
                    </SalesLine>
                    <SalesLine class="entity">
                        <ExtLineNum>40</ExtLineNum>
                        <ItemId>08254</ItemId>
                        <SalesId>QN00000949</SalesId>
                        <SalesOrderStatus>CancelledBySales</SalesOrderStatus>
                        <SalesQty>1320.00</SalesQty>
                        <SalesUnit>st</SalesUnit>
                        <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
                    </SalesLine>
                </SalesTable>
            </SalesOrder>
        </MessageParts>
    </Body>
</Envelope>

Expected result:

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
    <Header>
        <MessageId>{9CEDBBC7-5AF3-4A8B-AC68-49F1E0D8402A}</MessageId>
        <SourceEndpoint>hwf</SourceEndpoint>
        <DestinationEndpoint>HWF_ORDRSP</DestinationEndpoint>
        <Action>http://schemas.microsoft.com/dynamics/2008/01/services/SalesSalesOrderService/read</Action>
    </Header>
    <Body>
        <MessageParts xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
            <SalesOrder xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">
                <SalesTable class="entity">
                    <CustAccount>00003</CustAccount>
                    <DeliveryDate>2019-10-21</DeliveryDate>
                    <POMOrderId>0002539819</POMOrderId>
                    <PurchOrderFormNum>4500143886</PurchOrderFormNum>
                    <SalesId>QN00000949</SalesId>
                    <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                    <SalesLine class="entity">
                        <ExtLineNum>10</ExtLineNum>
                        <ItemId>08201</ItemId>
                        <SalesId>QN00000949</SalesId>
                        <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                        <SalesQty>1320.00</SalesQty>
                        <SalesUnit>st</SalesUnit>
                        <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
                    </SalesLine>
                    <SalesLine class="entity">
                        <ExtLineNum>30</ExtLineNum>
                        <ItemId>08238</ItemId>
                        <SalesId>QN00000949</SalesId>
                        <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                        <SalesQty>1296.00</SalesQty>
                        <SalesUnit>st</SalesUnit>
                        <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
                    </SalesLine>
                </SalesTable>
            </SalesOrder>
        </MessageParts>
    </Body>
</Envelope>

XSL I've created so far:

<!-- Michael van den Dool 18-10-2019 17:46 filter saleslines  -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

    xmlns:xs="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder" exclude-result-prefixes="xs" version="2.0">

    <!-- Copy everything -->

    <xsl:template match="node() | @*">

        <xsl:copy>

            <xsl:apply-templates select="node() | @*"/>

        </xsl:copy>

    </xsl:template>



    <!-- Match elements which need to be filtered and do not copy them to the output -->

    <xsl:template match="SalesTable/SalesLine[not(SalesTable/SalesLine/SalesOrderStatus/text() = 'SalesOrder')]"/>

</xsl:stylesheet>

When running the xsl nothing is filtered out. I think it's in the namespace / hierarchy somewhere. but I'm still an amateur in xsl, sorry..

Upvotes: 1

Views: 83

Answers (1)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243449

Here is a simple, short XSLT 1.0 solution.

Your main problem is failing to specify in the match pattern the namespace of the elements -- they are not in "no namespace"

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:x="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

  <xsl:template match="x:SalesLine[not(x:SalesOrderStatus = 'SalesOrder')]"/>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<Envelope xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
    <Header>
        <MessageId>{9CEDBBC7-5AF3-4A8B-AC68-49F1E0D8402A}</MessageId>
        <SourceEndpoint>hwf</SourceEndpoint>
        <DestinationEndpoint>HWF_ORDRSP</DestinationEndpoint>
        <Action>http://schemas.microsoft.com/dynamics/2008/01/services/SalesSalesOrderService/read</Action>
    </Header>
    <Body>
        <MessageParts>
            <SalesOrder xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">
                <SalesTable class="entity">
                    <CustAccount>00003</CustAccount>
                    <DeliveryDate>2019-10-21</DeliveryDate>
                    <POMOrderId>0002539819</POMOrderId>
                    <PurchOrderFormNum>4500143886</PurchOrderFormNum>
                    <SalesId>QN00000949</SalesId>
                    <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                    <SalesLine class="entity">
                        <ExtLineNum>10</ExtLineNum>
                        <ItemId>08201</ItemId>
                        <SalesId>QN00000949</SalesId>
                        <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                        <SalesQty>1320.00</SalesQty>
                        <SalesUnit>st</SalesUnit>
                        <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
                    </SalesLine>
                    <SalesLine class="entity">
                        <ExtLineNum>20</ExtLineNum>
                        <ItemId>08236</ItemId>
                        <SalesId>QN00000949</SalesId>
                        <SalesOrderStatus>Sent</SalesOrderStatus>
                        <SalesQty>1296.00</SalesQty>
                        <SalesUnit>st</SalesUnit>
                        <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
                    </SalesLine>
                    <SalesLine class="entity">
                        <ExtLineNum>30</ExtLineNum>
                        <ItemId>08238</ItemId>
                        <SalesId>QN00000949</SalesId>
                        <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                        <SalesQty>1296.00</SalesQty>
                        <SalesUnit>st</SalesUnit>
                        <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
                    </SalesLine>
                    <SalesLine class="entity">
                        <ExtLineNum>40</ExtLineNum>
                        <ItemId>08254</ItemId>
                        <SalesId>QN00000949</SalesId>
                        <SalesOrderStatus>CancelledBySales</SalesOrderStatus>
                        <SalesQty>1320.00</SalesQty>
                        <SalesUnit>st</SalesUnit>
                        <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
                    </SalesLine>
                </SalesTable>
            </SalesOrder>
        </MessageParts>
    </Body>
</Envelope>

The wanted, correct result is produced:

<Envelope xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
   <Header>
      <MessageId>{9CEDBBC7-5AF3-4A8B-AC68-49F1E0D8402A}</MessageId>
      <SourceEndpoint>hwf</SourceEndpoint>
      <DestinationEndpoint>HWF_ORDRSP</DestinationEndpoint>
      <Action>http://schemas.microsoft.com/dynamics/2008/01/services/SalesSalesOrderService/read</Action>
   </Header>
   <Body>
      <MessageParts>
         <SalesOrder xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">
            <SalesTable class="entity">
               <CustAccount>00003</CustAccount>
               <DeliveryDate>2019-10-21</DeliveryDate>
               <POMOrderId>0002539819</POMOrderId>
               <PurchOrderFormNum>4500143886</PurchOrderFormNum>
               <SalesId>QN00000949</SalesId>
               <SalesOrderStatus>SalesOrder</SalesOrderStatus>
               <SalesLine class="entity">
                  <ExtLineNum>10</ExtLineNum>
                  <ItemId>08201</ItemId>
                  <SalesId>QN00000949</SalesId>
                  <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                  <SalesQty>1320.00</SalesQty>
                  <SalesUnit>st</SalesUnit>
                  <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
               </SalesLine>
               <SalesLine class="entity">
                  <ExtLineNum>30</ExtLineNum>
                  <ItemId>08238</ItemId>
                  <SalesId>QN00000949</SalesId>
                  <SalesOrderStatus>SalesOrder</SalesOrderStatus>
                  <SalesQty>1296.00</SalesQty>
                  <SalesUnit>st</SalesUnit>
                  <ShippingDateConfirmed>2019-10-21</ShippingDateConfirmed>
               </SalesLine>
            </SalesTable>
         </SalesOrder>
      </MessageParts>
   </Body>
</Envelope>

Upvotes: 1

Related Questions