XPath expression - or not working as expected

I try to do a not so hard xpath 2.0 expression but still, I'm blocked.

Here is the xml file:

<request>
<cmt:transmission>
    <cmt:workflow>
        <cm:work>
            <cm:expression>
                <cm:manifestation>
                    <cm:reference_manifestation format="FMX4"
                        sequence="1">file1.xml</cm:reference_manifestation>
                    <cm:reference_manifestation format="TIFF"
                        sequence="2">file2.tif</cm:reference_manifestation>
                    <cm:reference_manifestation format="FMX4"
                        sequence="3">file3.xml</cm:reference_manifestation>
                    <cm:extension xsi:type="ojext:OJManifestationExtensionType">
                        <ojext:manifestation_type>fmx4</ojext:manifestation_type>
                    </cm:extension>
                </cm:manifestation>
            </cm:expression>        
        </cm:work>
    </cmt:workflow>
</cmt:transmission>

The XPath I try to do is: If my manifestation_type is 'fmx4' then the format of my reference_manifestation must be 'FMX4' or 'TIFF'. If my rule is not respected then I want to get the manifestation.

Here is my current invalid xpath:

descendant::*:manifestation[*:extension/*:manifestation_type ='fmx4' and not (*:reference_manifestation/@format = 'FMX4' or *:reference_manifestation/@format = 'TIFF' ) ]

Can somebody help me?

Thank you

Upvotes: 1

Views: 393

Answers (1)

Mathias M&#252;ller
Mathias M&#252;ller

Reputation: 22617

Well, it is a pretty confusing expression.

//*[local-name() = 'manifestation'
and *[local-name() = 'extension']/*[local-name() = 'manifestation_type'] = 'fmx4'
and *[local-name() = 'reference_manifestation']/@format[. != 'TIFF' and . != 'FMX4']]

In plain English, line for line:

Look for elements anywhere in the document, if their local name is "manifestation".

Also, there must be at least one child element with the local name "extension" and this element in turn must have a child with the local name "manifestation_type" and its textual content must be "fmx4".

Also, the original "manifestation" element must have at least one other child element with the local name "reference_manifestation" and an attribute "format" whose value is neither "TIFF" nor "FMX4".

With your current input XML, the path expression returns nothing (because the rules are respected). If you change the input to the following (and also declare all the namespaces that were missing!):

<request xmlns:cm="www.example.com" xmlns:cmt="www.example2.com"
xmlns:ojext="www.example3.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<cmt:transmission>
    <cmt:workflow>
        <cm:work>
            <cm:expression>
                <cm:manifestation>
                    <cm:reference_manifestation format="FMX4"
                        sequence="1">file1.xml</cm:reference_manifestation>
                    <cm:reference_manifestation format="TIFF"
                        sequence="2">file2.tif</cm:reference_manifestation>
                    <cm:reference_manifestation format="SOMETHINGELSE"
                        sequence="3">file3.xml</cm:reference_manifestation>
                    <cm:extension xsi:type="ojext:OJManifestationExtensionType">
                        <ojext:manifestation_type>fmx4</ojext:manifestation_type>
                    </cm:extension>
                </cm:manifestation>
            </cm:expression>        
        </cm:work>
    </cmt:workflow>
</cmt:transmission>
</request>

Then the manifestation is returned, because one format attribute deviates from the allowed values.


Note 1: in cases like these it's insanely complicated in part because you ignore the namespaces present in the document. If you would register or declare those namespaces appropriately and use prefixes in the path expression, it would help a lot.

Note 2: There is nothing 2.0 about this path expression, and the same applies to your original expression.

Upvotes: 1

Related Questions