Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use the Xpath function 'contains()' to return nothing if it's search param is blank or missing/false?

I'm trying to write an Xpath Statement (1.0) that can read info from a 'search' node and perform a search using it.

I was making some nice progress, but stumbled across an issue where if an attribute (used for a value in the search) is empty or doesn't exist, it fails.

Code Edited to simplify Example:

So Here is my sample XML:

<xml>
    <files>
        <file name="foo" description="" rating="4"/>
        <file name="food" description="" rating="4"/>
        <file name="foobar" description="" rating="3"/>
        <file name="bar" description="" rating="3"/>
        <file name="barter" description="" rating="3"/>
        <file name="barterer" description="" rating="2"/>
    </files>
    <searches>
        <search id="1">
            <exclude>
                <file term="foo"/>
            </exclude>
        </search>
    </searches>
</xml>

And working XPATH:

//files/file[
            not(contains(@name, //search[@id='1']/exclude/file/@term))
]

It works as expected...

However if the an expected attribute is missing or empty it will fail to work. I think because: contains(@attrib, "") matches everything for some-reason, therefore a not() will always match nothing if the attribute is "" or not present.

For Example, if I alter the exclude fragment of XML to this it fails:

            <exclude>
                <file term=""/>
            </exclude>

with this too:

            <exclude></exclude>

Is there a way to Check for an empty value and not perform the select? or is there perhaps a better way of structuring the Logic. Bare in mind I cannot use Conditionals or the other functions in Xpath2.0.

like image 449
Futile32 Avatar asked Sep 02 '12 12:09

Futile32


People also ask

What is XPath command?

XPath (XML Path Language) is an expression language designed to support the query or transformation of XML documents. It was defined by the World Wide Web Consortium (W3C) and can be used to compute values (e.g., strings, numbers, or Boolean values) from the content of an XML document.


1 Answers

Why does the Xpath function contains() return everything if it search param is blank or missing?

Because that is what the XPath specification says the contains() function should do:

If the value of $arg2 is the zero-length string, then the function returns true.

You could adjust your XPath and simplify some of the conditions with the following:

//files/file[
            (  
                (
                    not(//search[@id='1']/include/file/@term)
                    or
                    (
                    contains(@name, //search[@id='1']/include/file/@term) 
                    or
                    contains(@description, //search[@id='1']/include/file/@term) 
                    ) 
                )
                or
                contains(@rating, //search[@id='1']/include/file/@rating)   
            )    
            and 
            ( 
                 (
                    not(//search[@id='1']/exclude/file/@term)
                    or
                    (
                    not(contains(@name, //search[@id='1']/exclude/file/@term)) 
                    and
                    not(contains(@description, //search[@id='1']/exclude/file/@term))
                    )
                )
                and
                (
                    not(//search[@id='1']/exclude/file/@rating)
                    or
                    not(contains(@rating, //search[@id='1']/exclude/file/@rating))
                )
            )

            ]
like image 63
Mads Hansen Avatar answered Oct 15 '22 22:10

Mads Hansen