Nokogiri可以搜索“?xml-stylesheet”标签吗?

时间:2010-08-22 16:21:11

标签: ruby xml nokogiri

我需要解析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 个答案:

答案 0 :(得分:2)

Nokogiri无法搜索XML处理指令的标签。你可以像这样访问它们:

doc.children[0]

答案 1 :(得分:1)

这不是XML元素;这是一个XML "Processing Instruction"。这就是为什么你无法用你的查询找到它。找到你想要的:

# 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中存在a bug,如果至少有一个字符,则会导致XML Declaration在文档中显示为Processing Instruction(可以是<?xml之前的空格。这就是为什么在上面我们专门搜索名为xml-stylesheet的处理指令。

修改:XPath表达式processing-instruction()[name()="foo"]等同于表达式processing-instruction("foo")。如XPath 1.0 spec

中所述
  

processing-instruction()测试可能有一个Literal参数;在这种情况下,对于任何名称等于Literal值的处理指令都是如此。

我编辑了上面的答案,使用较短的格式。