Phr*_*ogz 5 ruby xml xpath nokogiri
给定标记如:
<p>
<code>foo</code><code>bar</code>
<code>jim</code> and then <code>jam</code>
</p>
Run Code Online (Sandbox Code Playgroud)
我需要选择前三个<code>
- 但不是最后一个.逻辑是"选择code
具有先前或后续兄弟元素的所有元素也是a code
,除非存在一个或多个文本节点,它们之间具有非空白内容.
鉴于我正在使用Nokogiri(使用libxml2),我只能使用XPath 1.0表达式.
虽然需要一个棘手的XPath表达式,但是在Nokogiri文档上执行相同操作的Ruby代码/迭代也是可以接受的.
请注意,CSS 相邻兄弟选择器忽略非元素节点,因此选择nokodoc.css('code + code')
将错误地选择最后一个<code>
块.
Nokogiri.XML('<r><a/><b/> and <c/></r>').css('* + *').map(&:name)
#=> ["b", "c"]
Run Code Online (Sandbox Code Playgroud)
编辑:更多测试用例,为清楚起见:
<section><ul>
<li>Go to <code>N</code> and
then <code>Y</code><code>Y</code><code>Y</code>.
</li>
<li>If you see <code>N</code> or <code>N</code> then…</li>
</ul>
<p>Elsewhere there might be: <code>N</code></p>
<p><code>N</code> across parents.</p>
<p>Then: <code>Y</code> <code>Y</code><code>Y</code> and <code>N</code>.</p>
<p><code>N</code><br/><code>N</code> elements interrupt, too.</p>
</section>
Run Code Online (Sandbox Code Playgroud)
Y
应选择以上所有内容.没有N
应该被选中.其内容<code>
仅用于指示应选择的内容:您不能使用内容来确定是否选择元素.
出现的上下文元素<code>
无关紧要.它们可能出现在<li>
,它们可能出现在<p>
,它们可能出现在其他东西中.
我想<code>
一次选择所有连续运行.在其中一组中间有一个空格字符并不是一个错误Y
.
使用:
\n\n//code\n [preceding-sibling::node()[1][self::code]\n or\n preceding-sibling::node()[1]\n [self::text()[not(normalize-space())]]\n and\n preceding-sibling::node()[2][self::code]\n or\n following-sibling::node()[1][self::code]\n or\n following-sibling::node()[1]\n [self::text()[not(normalize-space())]]\n and\n following-sibling::node()[2][self::code]\n ]\n
Run Code Online (Sandbox Code Playgroud)\n\n基于 XSLT 的验证:
\n\n<xsl:stylesheet version="1.0"\n xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n <xsl:output omit-xml-declaration="yes" indent="yes"/>\n\n <xsl:template match="/">\n <xsl:copy-of select=\n "//code\n [preceding-sibling::node()[1][self::code]\n or\n preceding-sibling::node()[1]\n [self::text()[not(normalize-space())]]\n and\n preceding-sibling::node()[2][self::code]\n or\n following-sibling::node()[1][self::code]\n or\n following-sibling::node()[1]\n [self::text()[not(normalize-space())]]\n and\n following-sibling::node()[2][self::code]\n ]"/>\n </xsl:template>\n</xsl:stylesheet>\n
Run Code Online (Sandbox Code Playgroud)\n\n当此转换应用于提供的 XML 文档时:
\n\n<section><ul>\n <li>Go to <code>N</code> and\n then <code>Y</code><code>Y</code><code>Y</code>.\n </li>\n <li>If you see <code>N</code> or <code>N</code> then\xe2\x80\xa6</li>\n </ul>\n <p>Elsewhere there might be: <code>N</code></p>\n <p><code>N</code> across parents.</p>\n <p>Then: <code>Y</code> <code>Y</code><code>Y</code> and <code>N</code>.</p>\n <p><code>N</code><br/><code>N</code> elements interrupt, too.</p>\n</section>\n
Run Code Online (Sandbox Code Playgroud)\n\n计算包含的 XPath 表达式,并将选定的节点复制到输出:
\n\n<code>Y</code>\n<code>Y</code>\n<code>Y</code>\n<code>Y</code>\n<code>Y</code>\n<code>Y</code>\n
Run Code Online (Sandbox Code Playgroud)\n