如何使用 Nokogiri 将两个 XML 文件合并为一个? [英] How do I merge two XML files into one using Nokogiri?

查看:42
本文介绍了如何使用 Nokogiri 将两个 XML 文件合并为一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two XML files and want to merge them, but the tags that are already there should not be changed:

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可以吗?怎么样?

The previous tags should have the same values but with the addition of the new ones. Is that possible using Nokogiri? How?

起初我尝试在没有 Nokogiri 的情况下使用:

At first I tried without Nokogiri using:

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

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

But when I convert back to xml (xml1.to_xml) I get in wrong format:

"<?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,我想出了这个解决方案,但实际上,它太丑了,而且有一个错误.如果 xml2 没有元素,它将崩溃:

Using Nokogiri, I came up with this solution, but really, it is so ugly and have a bug. If the xml2 doesnt have a element it will crash:

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 的值.

Based on your samples and the desired output it appears you just want to replace the mat value in XML2 with the mat value from 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>

这不是真正的合并,而是简单的替换.如果问题更多,那么您的示例和所需的输出需要修改为更全面.

This isn't really a merge, it's a simple substitution. If there is more to the problem then your examples and desired output need to be modified to be more comprehensive.

这篇关于如何使用 Nokogiri 将两个 XML 文件合并为一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆