检查字符串是否符合XML格式

7
我想知道在Ruby中是否有类似于is_xml?(string)的函数,可以判断给定的字符串是否为XML格式。

你想区分XML和格式正确的HTML吗? - the Tin Man
嗨,Tin Man,答案是否定的。我有一些常规字符串和混合在一起的XML格式字符串。我想要将它们分开。 - mCY
2个回答

20
Nokogiri的parse使用一个简单的正则表达式测试来寻找<html>,以确定要解析的数据是HTML还是XML:
string =~ /^s*<[^Hh>]*html/ # Probably html

有类似的东西,查找XML声明可以作为一个起点:

string = '<?xml version="1.0"?><foo><bar></bar></foo>'
string.strip[/\A<\?xml/]
=> "<?xml"

如果返回值不是nil,则该字符串包含XML声明。测试此项非常重要,因为空字符串会欺骗后续步骤。

Nokogiri::XML('').errors.empty?
=> true

Nokogiri还有一个errors方法,该方法会在尝试解析格式错误的文档后返回一个错误数组。测试一下它的大小是否为零会有所帮助:

Nokogiri也有errors方法,可以返回尝试解析格式不正确的文档后得到的错误数组。检查该数组的长度是否为0可以帮助解决问题:

Nokogiri::XML('<foo>').errors
=> [#<Nokogiri::XML::SyntaxError: Premature end of data in tag foo line 1>]
Nokogiri::XML('<foo>').errors.empty?
=> false

Nokogiri::XML(string).errors.empty?
=> true
如果文档在语法上有效,它将是真的。
我刚刚测试了Nokogiri,看看它是否能区分常规字符串和真正的XML。
[2] (pry) main: 0> doc = Nokogiri::XML('foo').errors
[
    [0] #<Nokogiri::XML::SyntaxError: Start tag expected, '<' not found>
]

所以,你可以轻松地遍历文件并将它们分为XML和非XML两类:

require 'nokogiri'

[
  '',
  'foo',
  '<xml></xml>'
].group_by{ |s| (s.strip > '') && Nokogiri::XML(s).errors.empty? }
=> {false=>["", "foo"], true=>["<xml></xml>"]}

group_by的结果赋值给一个变量,你会得到一个可以检查是否为非XML (false)或XML (true)的哈希表。


太好了!这些细节非常有帮助。 - mCY
我添加了一些代码,你可能会觉得有用。 - the Tin Man

1

Ruby的String类或Active Support的String扩展中没有这样的功能,但是您可以使用Nokogiri来检测XML中的错误

begin
  bad_doc = Nokogiri::XML(badly_formed) { |config| config.strict }
rescue Nokogiri::XML::SyntaxError => e
  puts "caught exception: #{e}"
end

这并没有告诉我们太多信息:Nokogiri::XML('') { |config| config.strict } => #<Nokogiri::XML::Document:0x3fc9ba1c9a1c name="document">. 空字符串既不是 XML,也不是正确或不正确格式化的 XML。Nokogiri::XML('').errors 会更清晰地告诉你是否有错误。 - the Tin Man
@theTinMan 对的,该链接还提供了.errors用法的示例。puts bad_doc.errors - nurettin
谢谢你的回答。现在我知道该怎么做了~ - mCY

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接