tags:

views:

56

answers:

2

The source document like this:

<a>
 <b n=n1n1n1n1>
 <c1> drftgy </c1>
 </b>
<c2> dddd </c2>
</a>

how to check if the element name = c then we will do something...

+3  A: 

Use a number of standard XPath functions:

To find if the current node's name starts with the string "c" use:

starts-with(name(), 'c')

To find if the current node's name contains the string "c" use:

contains(name(), 'c')

To select all elements in the XML document, whose names start with "c" use:

//*[starts-with(name(), 'c')]

To select all elements in the XML document, whose names contain "c" use:

//*[contains(name(), 'c')]

Edit: The OP has asked an additional question: How to select all elements whose name is one in a set of names?

XPath 2.0:

  //*[name(.)= ('c1', 'c2', 'c3')]

This uses the general comparison operator = and selects all elements in the document whose name is one of the strings in the sequence ('c1', 'c2', 'c3').

This cannot be done only with XPath 1.0,

XSLT 1.0 + XPath 1.0:

This transformation:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <my:names>
  <name>c1</name>
  <name>c2</name>
  <name>c3</name>
 </my:names>

 <xsl:variable name="vNames" select=
  "document('')/*/my:names/*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/">
  <xsl:copy-of select="//*[name()=$vNames]"/>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document (corrected to be well-formed):

<a>
 <b n="n1n1n1n1">
 <c1> drftgy </c1>
 </b>
<c2> dddd </c2>
</a>

produces the wanted result:

<c1> drftgy </c1>
<c2> dddd </c2>
Dimitre Novatchev
thank you, and how to check with multiple values. For example: there are a lot kinds of tag c. So I wanna check for some not all. And the expression look like this://*[contains(name(), 'c1') or contains(name(), 'c2') or contains(name(), 'c3')]Instead of, //*[contains(name(), 'c1'|'c2'|'c3')]Which one is possible? and is there another solutions?
@user402802: I have added to my answer the solution to your last question expressed in your comment.
Dimitre Novatchev
@Dimitre: +1 for extend answer, specs link and XPath version distinction.
Alejandro
+1  A: 

With XPath 2.0 and XQuery 1.0 you could use //*[local-name() = ('c1', 'c2', 'c3')] or you could use matches with a regular expression e.g. //*[matches(local-name(), '^c[123]$')].

Martin Honnen