Может ли Nokogiri искать теги "? Xml-stylesheet"? - PullRequest
4 голосов
/ 22 августа 2010

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

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/templates/xslt/inspections/disclaimer_en.xsl"?>

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

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

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

`on_error': unexpected '?' after '' (Nokogiri::CSS::SyntaxError)

Ответы [ 2 ]

2 голосов
/ 22 августа 2010

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

doc.children[0]
1 голос
/ 01 сентября 2012

Это не элемент 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"

Поскольку инструкция обработки не является элементом, она не имеет атрибутов; вы не можете, например, попросить 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 должен быть хотя бы один символ (может быть пробел). Вот почему в вышеприведенном мы специально ищем инструкции по обработке с именем xml-stylesheet.

Редактировать : Выражение XPath processing-instruction()[name()="foo"] эквивалентно выражению processing-instruction("foo"). Как описано в спецификации XPath 1.0 :

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

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

...