Может ли Nokogiri искать теги "? Xml-stylesheet"?

Мне нужно проанализировать таблицу стилей XML:

Используя Nokogiri, я попробовал:

doc.search("?xml-stylesheet").first['href']

но я получаю ошибку:

`on_error': unexpected '?' after '' (Nokogiri::CSS::SyntaxError)
2 ответа

Nokogiri не может искать теги, которые являются инструкциями по обработке XML. Вы можете обращаться к ним следующим образом:

doc.children[0]


Это не элемент XML; это XML "Инструкция по обработке" . Вот почему вы не смогли найти его по вашему запросу. Чтобы найти его, вы хотите:

# Find the first xml-stylesheet PI
xss = doc.at_xpath('//processing-instruction("xml-stylesheet")')
# Find every xml-stylesheet PI
xsss = doc.xpath('//processing-instruction("xml-stylesheet")')

В действии:

require 'nokogiri'
xml = <<endxml <?xml="" version="1.0" encoding="UTF-8" ?="">
 <!--?xml-stylesheet type="text/xsl" href="/templates/disclaimer_en.xsl"?-->
 <root>Hi Mom!</root>
ENDXML
doc = Nokogiri.XML(xml)
xss = doc.at_xpath('//processing-instruction("xml-stylesheet")')
puts xss.name #=> xml-stylesheet
puts xss.content #=> type="text/xsl" href="/templates/disclaimer_en.xsl"
</endxml>

Так как Инструкция по обработке не является элементом, у нее нет атрибутов; вы не можете, например, запросить xss['type'] или xss['href']; вам нужно будет проанализировать содержимое как элемент, если вы этого хотите. Один из способов сделать это:

class Nokogiri::XML::ProcessingInstruction
 def to_element
 document.parse("<#{name} #{content}/>")
 end
end
p xss.to_element['href'] #=> "/templates/disclaimer_en.xsl"

Обратите внимание, что существует ошибка в Nokogiri или libxml2, которая вызовет Декларация XML появится в документе как Инструкция по обработке, если есть хотя бы один символ (может быть пробел) до <!--?xml</code-->. Вот почему в приведенном выше примере мы выполняем поиск специально для обработки инструкций с именем <code>xml-stylesheet.

<p> <span> Изменить</span>: выражение XPath <code>processing-instruction()[name()="foo"] эквивалентно выражению processing-instruction("foo"). Как описано в XPath 1.0 spec:

В тесте processing-instruction() может быть аргумент Literal; в этом случае это верно для любой команды обработки, которая имеет имя, равное значению Литерала.

Я отредактировал ответ выше, чтобы использовать более короткий формат.

licensed under cc by-sa 3.0 with attribution.