0

I need to be able to keep track of where in the document any particular value is. I would use XSL but the ecosystem I'm working in prevents that. I'm using the Java Saxon-HE 9.7.0-2 processor.

XML

<test>
    <value cat="fiction">At the edge of the orchard</value>
    <value cat="mythology">Hero with a thousand faces</value>
    <value cat="fiction">Spill simmer falter wither</value>
</test>

XPath

for $a in /test
    return
        (if ($a/value[@cat="mythology"]) then 
            $a/value[@cat="mythology"] else
            "")

What I would like to see come back is:

""
"Hero with a thousand faces"
""

What I'm currently seeing is:

"Hero with a thousand faces"

Link to videlibri xpath tester

Link to saxon code

3 Answers 3

1

I think you want to iterate on every value and do the check. The below xpath should work for you:

string-join((for $a in /test/value
                                return
                                    (if ($a[@cat='mythology']) then 
                                        concat('&quot;',$a,'&quot;') else
                                        '&quot;&quot;')),'&#xa;')

Simplified:

string-join((for $a in /test/value
            return
                concat('&quot;',($a[@cat='mythology'],'')[1], '&quot;'))
     ,'&#xa;')
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you; it is closer to what I need but now I'm in the position of having a to parse the return. What I get with this xPath is: &quot;&quot;&#xa;&quot;Hero with a thousand faces&quot;&#xa;&quot;&quot; Parsing that is risky for me because in reality what is in that block of text is unconstrained. I still may have to go with this solution if I can't come up with something better.
0

This is returning the empty strings I'm looking for:

for $a in /test/value
return
    if ($a[@cat='mythology']) then 
        $a[@cat='mythology'] else
        ""

Can someone explain why this xpath behaves differently from the one in the original question?

videlibri xpath tester

1 Comment

To answer my own question: The original loop of 'for $a in /test' is only one node so the containing if statement only ever gets evaluated once. In the version that works; I'm iterating over multiple nodes. This was made clear to me when I evaluated /test/value[@cat='fiction'] by itself without the loop and if statements. Another thank you for lingamurthy for getting me down the right path.
0

I think /test/value/(.[@cat = 'mythology'], '')[1] suffices and is a bit more compact than the for .. return if ... then ... else.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.