繁体   English   中英

如何使用Nokogiri将两个XML文件合并为一个?

[英]How do I merge two XML files into one using Nokogiri?

我有两个XML文件并希望合并它们,但不应更改已存在的标记:

XML 1:

<?xml version="1.0"?>
<formX xmlns="sdu:x">
  <identify>
    <mat>8</mat>
  </identify>
</formX>

XML 2:

<?xml version="1.0"?>
<formX xmlns="sdu:x">
  <identify>
    <mat>9999</mat>
    <name>John Smith</name>
  </identify>
</formX>

我希望结果是这样的:

<?xml version="1.0"?>
<formX xmlns="sdu:x">
  <identify>
    <mat>8</mat>
    <name>John Smith</name>
  </identify>
</formX>

以前的标签应该具有相同的值,但添加了新的标签。 这可能使用Nokogiri吗? 怎么样?

起初我试过没有Nokogiri使用:

xml1 = Hash.from_xml('<?xml version="1.0"?>
<formX xmlns="sdu:x">
  <identify>
    <mat>8</mat>
  </identify>
</formX>')

但是当我转换回xml(xml1.to_xml)时,我的格式错误:

"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n  <formX>\n    <xmlns>sdu:x</xmlns>\n    <identify>\n      <mat>8</mat>\n    </identify>\n  </formX>\n</hash>\n"

使用Nokogiri,我提出了这个解决方案,但实际上,它是如此丑陋并且有一个bug。 如果xml2没有元素,它将崩溃:

require 'nokogiri'

s = "<formAposentadoria xmlns=\"spu:aposentadoria\"><identificacao><matricula>8</matricula></identificacao></formAposentadoria>"
xml1 = Nokogiri::XML.parse s

s2 = "<formAposentadoria xmlns=\"spu:aposentadoria\"><identificacao><matricula>9</matricula><nome>John</nome></identificacao></formAposentadoria>"
xml2 = Nokogiri::XML.parse s2

def node_list elem, &proc
  return [] unless elem.class == Nokogiri::XML::Element
  str = proc.call(elem)
  [str] + elem.children.inject([]){|a,c| a+node_list(c,&proc)}.map{|e| "#{str}/#{e}"}
end

node_list(xml1.root){|e| e.name}.each do |x|
  caminho = '//xmlns:' + x.gsub('/', '/xmlns:')
  puts caminho
  if xml2.at_xpath( caminho ).children.children.count == 0
    xml2.at_xpath( caminho ).content = xml1.at_xpath( caminho ).content
  end
end

puts xml2.to_xml

根据您的样品,它出现在所需的输出,你只是想更换mat用在XML2价值mat从XML1值。

require 'nokogiri'

xml1 = Nokogiri::XML('<?xml version="1.0"?>
<formX xmlns="sdu:x">
  <identify>
    <mat>8</mat>
  </identify>
</formX>')

xml2 = Nokogiri::XML('<?xml version="1.0"?>
<formX xmlns="sdu:x">
  <identify>
    <mat>9999</mat>
    <name>John Smith</name>
  </identify>
</formX>')

xml2.at('mat').content = xml1.at('mat').content

puts xml2.to_xml

哪个输出:

<?xml version="1.0"?>
<formX xmlns="sdu:x">
  <identify>
    <mat>8</mat>
    <name>John Smith</name>
  </identify>
</formX>

这不是真正的合并,它是一个简单的替代。 如果问题还有其他问题,那么您的示例和所需输出需要修改为更全面。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM