2

我正在尝试获取具有qux某个属性的兄弟姐妹的属性列表,在这种情况下x,在属性foo和它的兄弟姐妹y的属性中。foo

//node[@foo="x" and following-sibling::node[@foo="y"]]/@qux | //node[@foo="y" and preceding-sibling::node[@foo="x"]]/@qux

这将创建一个列表,但与单独运行两个部分并将它们添加在一起相同,除了顺序。我需要一个qux彼此相邻的列表,所以每行两个qux元素的列表,显然是兄弟姐妹匹配的地方。

这可以在 xpath 中完成吗?如果可以,怎么做?如果没有,xquery 会完成这项工作吗?

编辑:示例文件和输出:

<database>
  <ds version="1">
    <node>
     <node foo="x" qux="hello"/>
     <node foo="y" qux="world"/>
    </node>
  </ds>
  <ds version="1">
    <node>
     <node>
       <node foo="x" qux="another"/>
       <node foo="y" qux="sentence"/>
       <node foo="y" qux="example"/>
       <node foo="z" qux="irrelevant"/>
     </node>
    </node>
  </ds>
  <ds version="1">
    <node>
      <node foo="y" qux="not"/>
      <node foo="z" qux="returned"/>
    </node>
  </ds>
</database>

请注意,我感兴趣的节点的深度是未知的,因此(我认为)使用 //node 是必要的。

查询应返回:

hello world
another sentence
another example
4

3 回答 3

1

使用单个 XPATH 语句获得结果并不容易——XPATH 真的是为 XML 导航而设计的。XSL 用于 XML 转换(这确实是您想要做的,即将属性列表 [hello][world] 转换为字符串“hello world”..)所以这里是获得所需结果所需的 XSL -

<?xml version="1.0" encoding="UTF-8"?>
<?altova_samplexml file:///C:/Users/Damien/Desktop/testXML.xml?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     
xmlns:fo="http://www.w3.org/1999/XSL/Format"  
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-
functions">
<xsl:template match="/">    
    <xsl:for-each select="//node[@foo='x' and following-
 sibling::node[@foo='y']]/@qux | //node[@foo='y' and preceding-
 sibling::node[@foo='x']]/@qux">
        <xsl:value-of select="."/>
        <xsl:text> </xsl:text>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>
于 2013-03-24T17:20:54.317 回答
1

根据 OP 对 XPath 2.0 解决方案的兴趣:

这个 XPath 2.0 表达式

for $n in //node[@foo eq 'x' and following-sibling::*[1][self::node[@foo eq 'y']]]
 return
   ( ($n|$n/following-sibling::*[1])/@qux/string(), '&#xA;')

产生想要的结果

于 2013-03-25T16:00:21.653 回答
0

由于缺乏对要求的完全理解,但这样的事情不会起作用吗?

//@qux[../@foo = 'x' or ../@bar='y']
于 2013-03-24T17:50:08.110 回答