我有一些看起来像这样的XML:
<container>
<type>01</type>
<text>one</text>
</container>
<container>
<type>02</type>
<text>two</text>
</container>
编辑 container
s的顺序不固定。
我正在使用xPath(通过ruby的nokogiri)从本文档中选择文本。我希望text
中的container
能够使用type
02,但是text
的{{1}}带container
如果不存在,则为01。
我能做到
type
哪个会给我两个元素,然后我可以使用一些ruby来排序并选择正确的元素(因为这将首先返回01元素),但这感觉很笨拙。
我已经搜索了stackoverflow并且没有什么可以立即显示允许我使用简单的xpath对元素输出进行排序,但是有没有办法命令xpath获取一个元素,但如果它不存在则回退到另一个?
干杯!
答案 0 :(得分:2)
不确定你是否喜欢它,但它可以做你想要的:
concat(substring(//container[type/text() = '02']/text,1,string-length(//container[type/text()='02'])*boolean(//container[type/text()='02']/text())),substring(//container[type/text() = '01']/text,1,string-length(//container[type/text()='01'])*number(boolean(//container[type/text()='01']/text())and not(boolean(//container[type/text()='02']/text())))))
我会在一秒钟内将其分解......
好的,所以这部分:
的concat(
substring(//container[type/text() = '02']/text,1,string-length(//container[type/text()='02'])*boolean(//container[type/text()='02']/text())),
如果存在,则从类型= 2中抓取<text>
。
这部分:
substring(//container[type/text() = '01']/text,1,string-length(//container[type/text()='01'])
从type = 1中获取<text>
,并且只有在使用此类型不存在type = 2时才返回它:
*number(boolean(//container[type/text()='01']/text())and not(boolean(//container[type/text()='02']/text())))))
希望有助于清理它,我知道你在寻找干净的东西,但是对于你想要使用XPath的东西,它有点乱。
答案 1 :(得分:0)
如果订单已修复,您可以选择两个,然后选择最后一个。它将是02,如果只有02,则02,如果文档中有一个01 ......
(/container/type[text() = "02" or text() = "01"]/parent::container)[last()]
或更短,因为节点的值是其文本,并且比较只查找匹配对:
(/container[type = ("01", "02")])[last()]
(至少在XPath 2中有效,不确定在XPath 1中是否相同)
-
编辑:
实际上这很容易。您可以查看//container[type = "02"]
,如果有一个类型为02的容器,那么您可以获取所有02个容器和所有01个容器,如果没有类型02容器,则导致:
//container[type = "02" or (type = "01" and not(//container[type = "02"]))]
它很慢
答案 2 :(得分:0)
var wdata = [];
$(document).on('click', '.is-accordion-submenu-parent > a', function (e) {
if (Foundation.MediaQuery.is('small only')) {
var href = $(this).attr('href'),
date = new Date(),
diff = date - wdata.parentClickDate;
if (wdata.parentHref == href && diff < 1000) {
window.location.href = href
}
wdata.parentHref = href;
wdata.parentClickDate = date;
}
});
外部括号从具有文本值(//container/type[.='02'], //container/type[.='01'])[1]/..
的type元素开始,然后由具有文本值02
的类型构成一个序列。 01
运算符会忽略所有未定义的值,因此,如果缺少一个值,则该序列仅由另一个组成,并且如果两个都缺失,则为空序列。
,
从该序列中选择第一项
[1]
是/..
的缩写语法,在这种情况下等同于您的parent::node()
。
您可能希望它能起作用:
parent::container
但是(至少在撒克逊语中)这给了您两个容器;或这样:
//container/(type[.='02'],type[.='01'])[1]/..
但这会为您提供(//container/(type[.='02'],type[.='01']))[1]/..
容器,因为括号的结果是两个节点均以文档顺序。