ber*_*kes 17 ruby xml json nokogiri
我有一些解析Nokogiri::XML::Document对象,我想打印为JSON.
我可以将它变成一个字符串,将其解析为哈希,使用active-record或Crack然后使用Hash.to_json; 但这既丑陋又依赖于manay库.
有没有更简单的方法?
根据评论中的请求,例如,XML <root a="b"><a>b</a></root>可以表示为JSON:
<root a="b"><a>b</a></root> #=> {"root":{"a":"b"}}
<root foo="bar"><a>b</a></root> #=> {"root":{"a":"b","foo":"bar"}}
Run Code Online (Sandbox Code Playgroud)
这也是我现在用Crack得到的.实际上,实体和子标签之间的冲突是一个潜在的问题,但我自己构建了大部分XML,因此最简单的方法就是完全避免这些冲突:)
odi*_*apc 43
这个对我有用:
Hash.from_xml(@nokogiri_object.to_xml).to_json
Run Code Online (Sandbox Code Playgroud)
此方法使用主动支持,因此如果您不使用rails,则手动包含活动支持核心扩展:
require 'active_support/core_ext/hash'
Run Code Online (Sandbox Code Playgroud)
Phr*_*ogz 14
这是一种方法.正如我的评论所指出的,"正确"的答案取决于你的输出应该是什么.JSON中没有XML节点的规范表示,因此所涉及的库中没有构建这样的功能:
require 'nokogiri'
require 'json'
class Nokogiri::XML::Node
def to_json(*a)
{"$name"=>name}.tap do |h|
kids = children.to_a
h.merge!(attributes)
h.merge!("$text"=>text) unless text.empty?
h.merge!("$kids"=>kids) unless kids.empty?
end.to_json(*a)
end
end
class Nokogiri::XML::Document
def to_json(*a); root.to_json(*a); end
end
class Nokogiri::XML::Text
def to_json(*a); text.to_json(*a); end
end
class Nokogiri::XML::Attr
def to_json(*a); value.to_json(*a); end
end
xml = Nokogiri::XML '<root a="b" xmlns:z="zzz">
<z:a>Hello <b z:x="y">World</b>!</z:a>
</root>'
puts xml.to_json
Run Code Online (Sandbox Code Playgroud)
{
"$name":"root",
"a":"b",
"$text":"Hello World!",
"$kids":[
{
"$name":"a",
"$text":"Hello World!",
"$kids":[
"Hello ",
{
"$name":"b",
"x":"y",
"$text":"World",
"$kids":[
"World"
]
},
"!"
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
请注意,上面完全忽略了名称空间,这可能是您想要的,也可能不是.
这是另一种转换为JsonML的替代方案.虽然这是一个有损转换(它不支持注释节点,DTD或命名空间URL),并且格式在设计上有点"傻"(第一个子元素处于[1]或[2]取决于属性是否存在),它确实指示元素和属性的名称空间前缀:
require 'nokogiri'
require 'json'
class Nokogiri::XML::Node
def namespaced_name
"#{namespace && "#{namespace.prefix}:"}#{name}"
end
end
class Nokogiri::XML::Element
def to_json(*a)
[namespaced_name].tap do |parts|
unless attributes.empty?
parts << Hash[ attribute_nodes.map{ |a| [a.namespaced_name,a.value] } ]
end
parts.concat(children.select{|n| n.text? ? (n.text=~/\S/) : n.element? })
end.to_json(*a)
end
end
class Nokogiri::XML::Document
def to_json(*a); root.to_json(*a); end
end
class Nokogiri::XML::Text
def to_json(*a); text.to_json(*a); end
end
class Nokogiri::XML::Attr
def to_json(*a); value.to_json(*a); end
end
xml = Nokogiri::XML '<root a="b" xmlns:z="zzz">
<z:a>Hello <b z:x="y">World</b>!</z:a>
</root>'
puts xml.to_json
#=> ["root",{"a":"b"},["z:a","Hello ",["b",{"z:x":"y"},"World"],"!"]]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11605 次 |
| 最近记录: |