By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,916 Members | 1,306 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,916 IT Pros & Developers. It's quick & easy.

select nodes where a grandchild's text is not some value?

P: 2
I have some XML that I want to transform to some XML:
Expand|Select|Wrap|Line Numbers
  1. <element>
  2.     <child>
  3.         <grandchild>
  4.             otherWord
  5.         </grandchild>
  6.         <grandchild>
  7.             triggerExclusion
  8.         </grandchild>
  9.     </child>
  10. </element>
  11. <element>
  12.     <child>
  13.         <grandchild>
  14.             otherWord
  15.         </grandchild>
  16.     </child>
  17. </element>
  18.  
I want to copy elements where 'triggerExclusion' is not the text of its grandchild subelement. In this example I want to copy the second element, not the first.

This doesn't work for me:
Expand|Select|Wrap|Line Numbers
  1. <template match="element[not(child/grandchild eq 'triggerExclusion')"]>
  2.     <copy>
  3.         <apply-templates/>
  4.     </copy>
  5. </template>
  6.  
My Saxon warns that a sequence can't be the first argument of the eq operator, and, I guess, only looks at the first grandchild.

Please, how do I select elements where a descendent of arbitrary depth has some value?

TIA
Sep 22 '08 #1
Share this Question
Share on Google+
5 Replies


MarkoKlacar
Expert 100+
P: 296
Hi,

What you could do is select every child-element that doesn't contain a grandchild with the text "triggerExclusion".

It could look something like this:
(don't quite remember the syntax, but isn't text() a function that returns the value of an element?? In this case it could be "triggerExclusion"...anyway)

[HTML]//child/grandchild/text() != "triggerExclusion"[/HTML]

That should at least get you started if you haven't solved it already.

/MK
Sep 22 '08 #2

P: 2
thank you for the thought. This would select grandchild elements that don't have the trigger. What I want is to select elements such that the grandchild doesn't have the trigger.

Something like --
Expand|Select|Wrap|Line Numbers
  1. //element[some test on grandchild I can't figure]
  2.  
Sep 23 '08 #3

Dormilich
Expert Mod 5K+
P: 8,639
thank you for the thought. This would select grandchild elements that don't have the trigger. What I want is to select elements such that the grandchild doesn't have the trigger.
Expand|Select|Wrap|Line Numbers
  1. element[child/grandchild/text() != 'triggerExclusion']
note: about the same as in your post...

regards
Sep 23 '08 #4

jkmyoung
Expert 100+
P: 2,057
Expand|Select|Wrap|Line Numbers
  1. element[child/grandchild/text() != 'triggerExclusion']
note: about the same as in your post...

regards
Wouldn't this select the first element since it has a child/grandchild node that isn't equal to triggerExclusion?

I would suggest just replacing the eq with a =.

Expand|Select|Wrap|Line Numbers
  1. <xsl:template match="element[not (child/grandchild = 'triggerExclusion')]">
  2. <xsl:copy-of select="."/>
  3. </xsl:template>
  4. <xsl:template match="element"/>
  5.  
Sep 23 '08 #5

Dormilich
Expert Mod 5K+
P: 8,639
Wouldn't this select the first element since it has a child/grandchild node that isn't equal to triggerExclusion?
I don't think so. It will select all <element> elements, that have not even one <grandchild> element with "triggerException". In this case, it should select the second one. note that the expression child/grandchild/text() is actually a node-set*, since there are two <grandchild> elements.

Or to ask it the other way round: what's the difference between element[child/grandchild/text() != 'triggerExclusion']** and element[not(child/grandchild/text() = 'triggerExclusion')] ? to me it is the same.

in this case (string) grandchild/text() and (string) grandchild gives the same, because there are no further child elements with text nodes (see specs @ w3c)

* you can test it with count(child/grandchild/text()), though I'm quite positive that the result will be 2
** expanded XPath is child::element[child::child/child::grandchild/child::text()]
Sep 23 '08 #6

Post your reply

Sign in to post your reply or Sign up for a free account.