3

I have below XML

<Root>
    <Element>
        <batch_id>Jan_22_2021_18</batch_id>
        <proposal_id>130994</proposal_id>
        <proposal_name>Brazil </proposal_name>
        <subregion>1234</subregion>
        <currency>BRL</currency>
    </Element>
    <Element>
        <batch_id>Jan_22_2021_18</batch_id>
        <proposal_id>130994</proposal_id>
        <proposal_name>Brazil </proposal_name>
        <subregion>7225</subregion>
        <currency>BRL</currency>
    </Element>
        <Element>
        <batch_id>Jan_22_2021_18</batch_id>
        <proposal_id>130994</proposal_id>
        <proposal_name>Brazil </proposal_name>
        <subregion>1111</subregion>
        <currency>BRL</currency>
    </Element>
</Root>

below XPaths

  1. Working:

    /Root/Element[(subregion ='7515') or (subregion ='7225') or (subregion ='1234') or (subregion ='8360') or (subregion ='8385') or (subregion ='8435') or (subregion ='8585')]
    
  2. Not working

    /Root/Element[(subregion !='7515') or (subregion !='7225') or (subregion !='1234') or (subregion !='8360') or (subregion !='8385') or (subregion !='8435') or (subregion !='8585')]
    

Can you explain why?

kjhughes
  • 106,133
  • 27
  • 181
  • 240
Yatan
  • 89
  • 5

1 Answers1

2

You have a logical flaw.

The opposite of A or B is not not(A) or not(B); it is not(A or B), or equivalently per De Morgan, not(A) and not(B).

So, if you want that other Elements – the ones not selected by your "working" XPath – apply a logical not() to the entire disjunction,

/Root/Element[not((subregion ='7515') 
               or (subregion ='7225') 
               or (subregion ='1234') 
               or (subregion ='8360') 
               or (subregion ='8385') 
               or (subregion ='8435') 
               or (subregion ='8585'))]

or to the individual conditions of the corresponding conjunction:

/Root/Element[    not(subregion ='7515') 
              and not(subregion ='7225') 
              and not(subregion ='1234') 
              and not(subregion ='8360') 
              and not(subregion ='8385') 
              and not(subregion ='8435') 
              and not(subregion ='8585')]
kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • But he's not using `not(X = 'abc')`, he's using `X != 'abc'`, which in XPath doesn't do the same thing; and although that's not the cause of the problem in this case because `subregion` always selects a singleton, it ought to be explained. – Michael Kay Jan 26 '21 at 23:28
  • Although not the issue here, @MichaelKay's right that future readers should also be aware that `not(X = 'abc')` and `X != 'abc'` are different in XPath. See [Dimitre's answer here](https://stackoverflow.com/a/4629660/290085) or any of several other Q/A (e.g, [here](https://stackoverflow.com/questions/2273853/xpath-difference-between-not-and) or [here](https://stackoverflow.com/q/29261158/290085)) that cover that particular concept. – kjhughes Jan 27 '21 at 00:46