Xpath:选择节点但不选择特定的子元素

Ben*_*Ben 8 xpath

我有一个类似于以下的结构:

<page id='1'>
  <title>Page 1</title>    
  <page id='2'>
    <title>Sub Page 1</title>
  </page>
  <page id='3'>
    <title>Sub Page 2</title>
  </page>    
</page>
<page id='4'>
  <title>Page 2</title>
</page>
Run Code Online (Sandbox Code Playgroud)

我需要通过Id选择页面,但如果该页面有后代页面,我不想返回这些元素,但我确实想要该页面的其他元素.如果我选择Page 1我想要返回标题而不是子页面...

//page[@id=1]
Run Code Online (Sandbox Code Playgroud)

以上是第1页,但如何排除子页面?此外,页面中可以有任意数量的元素.

//page[@id=1]/*[not(self::page)]
Run Code Online (Sandbox Code Playgroud)

我发现这可以获得我想要的数据.但是,该数据作为一个对象数组返回,每个元素有一个对象,显然不包括元素名称??? 我正在使用PHP SimpleXML来获得它的价值.

Dim*_*hev 8

用途:

//page[@id=$yourId]/node()[not(self::page)]
Run Code Online (Sandbox Code Playgroud)

这将选择文档page中任何不属于任何子节点的子节点,pageid属性的字符串值等于包含在$yourId其中的字符串(最有可能的是,您将$yourId在上面用特定的所需字符串替换,例如'1').

这是一个简单的基于XSLT的验证:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pId" select="3"/>

 <xsl:template match="/">
     <xsl:copy-of select="//page[@id=$pId]/node()[not(self::page)]"/>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

当此转换应用于提供的XML文档时(包装在单个顶级节点中以使其格式良好):

<pages>
    <page id='1'>
        <title>Page 1</title>
        <page id='2'>
            <title>Sub Page 1</title>
        </page>
        <page id='3'>
            <title>Sub Page 2</title>
        </page>
    </page>
    <page id='4'>
        <title>Page 2</title>
    </page>
</pages>
Run Code Online (Sandbox Code Playgroud)

产生了想要的正确结果:

<title>Sub Page 2</title>
Run Code Online (Sandbox Code Playgroud)

请注意:一个假设是一个id唯一标识a 的值page.如果不是这样,则建议的XPath表达式将选择其属性的字符串值为的所有 page元素.id$yourId

如果是这种情况并且只能page选择一个元素,则OP必须指定应该选择page具有此元素的多个元素中的哪一个id.

例如,它可能是第一个:

(//page[@id=$yourId]/node()[not(self::page)])[1]
Run Code Online (Sandbox Code Playgroud)

或者最后一个:

(//page[@id=$yourId]/node()[not(self::page)])[last()]
Run Code Online (Sandbox Code Playgroud)

要么 ...