ruby – 如何将Nokogiri Document对象转换成JSON

前端之家收集整理的这篇文章主要介绍了ruby – 如何将Nokogiri Document对象转换成JSON前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一些解析了我想打印为 JSON的Nokogiri :: XML :: Document对象.

我可以去做一个字符串的路由,解析成一个哈希,使用活动记录或者Crack,然后是Hash.to_json;但是这是丑陋的,也是依靠方式太Manay图书馆.

有没有一个简单的方法

根据注释中的请求,例如XML< root a =“b”>< a> b< / a>< / root>可以表示为JSON:

  1. <root a="b"><a>b</a></root> #=> {"root":{"a":"b"}}
  2. <root foo="bar"><a>b</a></root> #=> {"root":{"a":"b","foo":"bar"}}

这就是我现在用Crack的东西.而且,确实,实体和子标签之间的冲突是一个潜在的问题,但是我自己构建了大部分的XML,所以我最容易避免这些碰撞:

解决方法

这是一种方法.正如我的评论所指出的,“正确的”答案取决于你的输出应该是什么.在JSON中没有XML节点的规范表示,因此所涉及的库中没有内置这样的功能
  1. require 'nokogiri'
  2. require 'json'
  3. class Nokogiri::XML::Node
  4. def to_json(*a)
  5. {"$name"=>name}.tap do |h|
  6. kids = children.to_a
  7. h.merge!(attributes)
  8. h.merge!("$text"=>text) unless text.empty?
  9. h.merge!("$kids"=>kids) unless kids.empty?
  10. end.to_json(*a)
  11. end
  12. end
  13. class Nokogiri::XML::Document
  14. def to_json(*a); root.to_json(*a); end
  15. end
  16. class Nokogiri::XML::Text
  17. def to_json(*a); text.to_json(*a); end
  18. end
  19. class Nokogiri::XML::Attr
  20. def to_json(*a); value.to_json(*a); end
  21. end
  22.  
  23. xml = Nokogiri::XML '<root a="b" xmlns:z="zzz">
  24. <z:a>Hello <b z:x="y">World</b>!</z:a>
  25. </root>'
  26. puts xml.to_json
  1. {
  2. "$name":"root","a":"b","$text":"Hello World!","$kids":[
  3. {
  4. "$name":"a","$kids":[
  5. "Hello ",{
  6. "$name":"b","x":"y","$text":"World","$kids":[
  7. "World"
  8. ]
  9. },"!"
  10. ]
  11. }
  12. ]
  13. }

请注意,以上内容完全忽略了命名空间,它们可能或可能不是您想要的.

转换为JsonML

这是另一个转换为JsonML的替代方法.虽然这是一个有损的转换(它不支持注释节点,DTD或命名空间URL),格式有点“愚蠢”的设计(第一个子元素在[1]或[2],取决于是否或不存在属性),它表示元素和属性的命名空间前缀:

  1. require 'nokogiri'
  2. require 'json'
  3. class Nokogiri::XML::Node
  4. def namespaced_name
  5. "#{namespace && "#{namespace.prefix}:"}#{name}"
  6. end
  7. end
  8. class Nokogiri::XML::Element
  9. def to_json(*a)
  10. [namespaced_name].tap do |parts|
  11. unless attributes.empty?
  12. parts << Hash[ attribute_nodes.map{ |a| [a.namespaced_name,a.value] } ]
  13. end
  14. parts.concat(children.select{|n| n.text? ? (n.text=~/\S/) : n.element? })
  15. end.to_json(*a)
  16. end
  17. end
  18. class Nokogiri::XML::Document
  19. def to_json(*a); root.to_json(*a); end
  20. end
  21. class Nokogiri::XML::Text
  22. def to_json(*a); text.to_json(*a); end
  23. end
  24. class Nokogiri::XML::Attr
  25. def to_json(*a); value.to_json(*a); end
  26. end
  27.  
  28. xml = Nokogiri::XML '<root a="b" xmlns:z="zzz">
  29. <z:a>Hello <b z:x="y">World</b>!</z:a>
  30. </root>'
  31. puts xml.to_json
  32. #=> ["root",{"a":"b"},["z:a","Hello ",["b",{"z:x":"y"},"World"],"!"]]

猜你在找的Ruby相关文章