【问题标题】:How can I make all XML tags lowercase in Nokogiri?如何在 Nokogiri 中将所有 XML 标签变为小写?
【发布时间】:2015-03-04 14:59:13
【问题描述】:

我正在解析从各种提要中获得的一些 XML。显然,一些 XML 偶尔会有一个全部大写的标记。我想将 XML 规范化为所有小写标签,以使搜索等更容易。

我想做的是这样的:

parsed = Nokogiri::XML.parse(xml_content)
node = parsed.css("title")  # => should return a Nokogiri node for the title tag

但是,某些 XML 文档具有该标记的“TITLE”。

无论它的标签是“title”、“TITLE”还是“Title”,我有哪些选择来获取该节点?

谢谢!

【问题讨论】:

标签: ruby xml nokogiri


【解决方案1】:

如果您想通过小写所有标签名称来转换您的 xml 文档,这是一种方法:

parsed = Nokogiri::XML.parse(xml_content)
parsed.traverse do |node|
  node.name = node.name.downcase if node.kind_of?(Nokogiri::XML::Element)
end

【讨论】:

  • 这似乎不起作用,因为块中的节点也是子节点,它们是 Nokogiri::XML::Text 并且没有 node_name。即:2.2.0 :075 > parsed.traverse {|node| node.node_name = node.node_name.downcase unless node.node_name == "document" } NoMethodError: undefined method downcase' for nil:NilClass from (irb):75:in block in irb_binding'
  • 但是,这似乎可行:parsed.traverse {|node| node.name = node.name.downcase if node.class == Nokogiri::XML::Element }
  • 我唯一的后续问题是:标签总是 Nokogiri::XML::Elements 还是我需要检查其他选项?
  • @DanSharp:是的,“标签”被正式称为“元素”——这是一个很好的解决方案。
  • node.node_namenode.name有区别吗?
【解决方案2】:

作为一种通用方法,您可以将所有元素(标签)名称转换为小写(例如,通过使用 XSLT 或其他解决方案),然后仅使用小写来执行所有 XPath/CSS 查询。

This XSLT solution should work;但是,我的 Ruby (2.0.0p481) 和/或 Nokogiri (1.5.6) 版本神秘地抱怨(也许是因为使用了“lower-case(...)”函数?也许 Nokogiri 不支持 XSLT v2?)

这是一个似乎可行的解决方案:

require 'nokogiri'

xslt = Nokogiri::XSLT(File.read('lower.xslt'))
# <?xml version="1.0" encoding="UTF-8"?>
# <xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
#   <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'" />
#   <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
#   <xsl:template match="*">
#     <xsl:element name="{translate(local-name(), $uppercase, $lowercase)}">
#       <xsl:apply-templates />
#     </xsl:element>
#   </xsl:template>
# </xsl:transform>

doc  = Nokogiri::XML(File.read('doc.xml'))
# <?xml version="1.0" encoding="UTF-8"?>
# <FOO>
#  <BAR>Bar</BAR>
#  <GAH>Gah</GAH>
#  <ZIP><DOO><DAH/></DOO></ZIP>
# </FOO>

puts xslt.transform(doc)
# <?xml version="1.0"?>
# <foo>
#   <bar>Bar</bar>
#   <gah>Gah</gah>
#   <zip><doo><dah/></doo></zip>
# </foo>

【讨论】:

  • 这可行,但它会删除任何标签上的任何附加属性。因此,如果我有:&lt;BAR stuff="whatever"&gt;Bar&lt;/BAR&gt;,它将变为:&lt;bar&gt;Bar&lt;/bar&gt;,而我失去了stuff="whatever"。这对我的特定需求可能无关紧要(我需要确保标签没有属性)。
  • @DanSharp:啊,好观察,我没想到要检查=(
猜你喜欢
  • 2014-02-19
  • 2013-02-06
  • 2015-02-04
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 2011-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多