XPath condition that accepts non-numerical characters

1.2k views Asked by At

I am currently constructing an XPath condition in SAP PI (receiver determination object) which should either route the message to receiver 1 or receiver 2.

The given documentID values that the business sends are as follows.

Receiver 1 receives messages within below documentID range

Range: "F00" to "F99"

Receiver 2 receives messages within below documentID range

Range: "FA0" to "FZ9"

Sample condition that I can think of, but not sure if this will work or if the logic is correct. Follow up question too, does greater/less than signs accept non-numerical characters?

Condition for Receiver 1

(/p1:Upload/ContainerEvent[WorkAssignmentID >= F00] EX  AND /p1:Upload/ContainerEvent[WorkAssignmentID <= F99] EX ) 

Condition for Receiver 2

(/p1:Upload/ContainerEvent[WorkAssignmentID >= FA0] EX  AND /p1:Upload/ContainerEvent[WorkAssignmentID <= FZ9] EX ) 

I am also thinking if substring can be used in XPath. Feel free to provide your inputs. Thanks

Regards, Charles Tan

2

There are 2 answers

0
Michael Kay On BEST ANSWER

Answer to your follow-up question ("does greater/less than signs accept non-numerical characters?"): in XPath 1.0, no, greater-than/less-than operate only on numerics. This changes in XPath 2.0.

1
Dimitre Novatchev On

Pure XPath 1.0 solution:

Receiver 1 receives messages within below documentID range Range: F00 to F99

/*/Upload/ContainerEvent
               [WorkAssignmentId
                 [string-length() = 3]
                 [starts-with(., 'F')][substring(.,2,2) >= 0][99 >= substring(.,2,2)]
                ]/EX

Receiver 2 receives messages within below documentID range Range: FA0 to FZ9

/*/Upload/ContainerEvent
               [WorkAssignmentId
                   [string-length() = 3]
                   [starts-with(., 'F')] 
                   [26 > string-length(
                            translate('ABCDEFGHIJKLMNOPQRSTUVWXYZ',substring(.,2,1), ''))]
                   [substring(.,3,1) >= 0][9 >= substring(.,3,1)]
                ]/EX

Here is XSLT - based verification:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/">
    <xsl:copy-of select=
    "/*/Upload/ContainerEvent
               [WorkAssignmentId
                 [string-length() = 3]
                 [starts-with(., 'F')][substring(.,2,2) >= 0][99 >= substring(.,2,2)]
                ]/EX"/>
==============================
    <xsl:copy-of select=
    "/*/Upload/ContainerEvent
               [WorkAssignmentId
                   [string-length() = 3]
                   [starts-with(., 'F')] 
                   [26 > string-length(
                            translate('ABCDEFGHIJKLMNOPQRSTUVWXYZ',substring(.,2,1), ''))]
                   [substring(.,3,1) >= 0][9 >= substring(.,3,1)]
                ]/EX"/>

  </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the following XML source document (none provided):

<p1>
    <Upload>
        <ContainerEvent>
            <WorkAssignmentId>F13</WorkAssignmentId>
            <EX>F13</EX>
        </ContainerEvent>
        <ContainerEvent>
            <WorkAssignmentId>F99</WorkAssignmentId>
            <EX>F99</EX>
        </ContainerEvent>
        <ContainerEvent>
            <WorkAssignmentId>E15</WorkAssignmentId>
            <EX>E15</EX>
        </ContainerEvent>
        <ContainerEvent>
            <WorkAssignmentId>FA7</WorkAssignmentId>
            <EX>FA7</EX>
        </ContainerEvent>
        <ContainerEvent>
            <WorkAssignmentId>FZ9</WorkAssignmentId>
            <EX>FZ9</EX>
        </ContainerEvent>
        <ContainerEvent>
            <WorkAssignmentId>FAB</WorkAssignmentId>
            <EX>FAB</EX>
        </ContainerEvent>
    </Upload>
</p1>

The wanted result is produced:

<EX>F13</EX>
<EX>F99</EX>
==============================
<EX>FA7</EX>
<EX>FZ9</EX>