tags:

views:

38

answers:

2

hi all,

this is my xml:

<root>
 <a>
  <b>
   <t>1</t>
  </b>
  <b>
   <t>2</t>
  </b>
 </a>
</root>

i want to ask: thats tell me if any t exist but i want true answer onky if b exsit and he have t=1

tanks

+1  A: 

The test you looking for is

//b/t[text() = '1']

This test can now be used in a template as the match, in a for-each loop as a selector or in a if statement as the test - e.g.:

<xsl:template match="//b/t[text() = '1']">
    <!-- all t children of b with a content of 1 -->
</xsl:template>

<xsl:for-each select="//b/t[text() = '1']">
    <!-- all t children of b with a content of 1 -->
</xsl:for-each>

<xsl:if test="//b/t[text() = '1']">
    <!-- This is the true case -->
</xsl:if>

Note:

  • This post is based on the asumption that you query from the root level and do not know where the b/t combination is. If you query from a point deeper in the hierarchy or know exactly the path to the b/t combination, you might want should to replace // with something more appropriate to avoid inefficiencies.
  • Also please note, that the text() function concatenates the textual content of all descendant nodes, i.e. only use it in the above way if you can be sure that there are no further descendants. The text() node-test returns all text nodes underneath the context node. (Martin, thanks for pointing this out).
Obalix
Obalix, why do you say "that the text() function concatenates the textual content of all descendant nodes"? That is not correct. In your XPath expression `//b/t[text() = '1']` the predicate in square brackets is true for a "t" element if it has at least one text child node with contents "1". If you used `//b/t[. = '1']` then the string value of a "t" element is compared to "1" and the string value is the concatenation of all text node descendants.
Martin Honnen
1. Using the `//` abbreviation in an XPath expression results in significant inefficiency. 2. Why have you provided syntactically illegal XSLT code?
Dimitre Novatchev
@Dimitre Novatchev: For 1.: Agreed, see my note; For 2.: Out of stupidity, sorry, corrected the samples.
Obalix
@Martin Honnen: Thanks, for pointing this out, I was unaware of this.
Obalix
+1  A: 

Use:

boolean(/*/*/b[t=1])

When evaluated against the provided XML document, the result is:

true()

Remember: Always try to avoid the // abbreviation, because it causes extremely inefficient traversing of the whole (sub) tree rooted at the context node.

Dimitre Novatchev