规则一:不要尝试使用正则表达式处理 HTML 或 XML。他们会让你失眠。
而是使用正确的工具,即 XML 解析器。Nokogiri是我选择的工具:
require 'nokogiri'
xml_in2 = '<?xml version="1.0" encoding="Windows-1251"?>
<vco:execution-context xmlns:vco="http://www.vmware.com/vco" xmlns="vco">
<vco:parameters>
<vco:parameter name="inputXml" type="string" description="" scope="local">
<vco:string>put parameter value here</vco:string>
</vco:parameter>
</vco:parameters>
</vco:execution-context>
'
doc = Nokogiri.XML(xml_in2)
doc.at('//vco:string').content = 'new and improved text'
puts doc.to_xml
哪个输出:
<?xml version="1.0" encoding="Windows-1251"?>
<vco:execution-context xmlns:vco="http://www.vmware.com/vco" xmlns="vco">
<vco:parameters>
<vco:parameter name="inputXml" type="string" description="" scope="local">
<vco:string>new and improved text</vco:string>
</vco:parameter>
</vco:parameters>
</vco:execution-context>
或者,插入 XML:
require 'nokogiri'
xml_in2 = '<?xml version="1.0" encoding="Windows-1251"?>
<vco:execution-context xmlns:vco="http://www.vmware.com/vco" xmlns="vco">
<vco:parameters>
<vco:parameter name="inputXml" type="string" description="" scope="local">
<vco:string>put parameter value here</vco:string>
</vco:parameter>
</vco:parameters>
</vco:execution-context>
'
doc = Nokogiri.XML(xml_in2)
doc.at('//vco:string').children = '<foo>some<bar>wild and crazy</bar>guys</foo>'
puts doc.to_xml
导致:
<?xml version="1.0" encoding="Windows-1251"?>
<vco:execution-context xmlns:vco="http://www.vmware.com/vco" xmlns="vco">
<vco:parameters>
<vco:parameter name="inputXml" type="string" description="" scope="local">
<vco:string><foo>some<bar>wild and crazy</bar>guys</foo></vco:string>
</vco:parameter>
</vco:parameters>
</vco:execution-context>
编辑:
require 'nokogiri'
xml_in2 = '<?xml version="1.0" encoding="Windows-1251"?>
<vco:execution-context xmlns:vco="http://www.vmware.com/vco" xmlns="vco">
<vco:parameters>
<vco:parameter name="inputXml" type="string" description="" scope="local">
<vco:string>put parameter value here</vco:string>
</vco:parameter>
</vco:parameters>
</vco:execution-context>
'
doc = Nokogiri.XML(xml_in2)
doc.at('//vco:string').content = "<tag><stillonetag>value</stillonetag></tag>"
puts doc.to_xml
现在是:
<?xml version="1.0" encoding="Windows-1251"?>
<vco:execution-context xmlns:vco="http://www.vmware.com/vco" xmlns="vco">
<vco:parameters>
<vco:parameter name="inputXml" type="string" description="" scope="local">
<vco:string><tag><stillonetag>value</stillonetag></tag></vco:string>
</vco:parameter>
</vco:parameters>
</vco:execution-context>
# encoding: UTF-8
require 'nokogiri'
xml_in2 = '<?xml version="1.0" encoding="Windows-1251"?>
<vco:execution-context xmlns:vco="http://www.vmware.com/vco" xmlns="vco">
<vco:parameters>
<vco:parameter name="inputXml" type="string" description="" scope="local">
<vco:string>put parameter value here</vco:string>
</vco:parameter>
</vco:parameters>
</vco:execution-context>
'
doc = Nokogiri.XML(xml_in2)
doc.encoding = 'UTF-8'
doc.at('//vco:string').content = "<operation>информация</operation>"
puts doc.to_xml
和输出:
<?xml version="1.0" encoding="UTF-8"?>
<vco:execution-context xmlns:vco="http://www.vmware.com/vco" xmlns="vco">
<vco:parameters>
<vco:parameter name="inputXml" type="string" description="" scope="local">
<vco:string><operation>информация</operation></vco:string>
</vco:parameter>
</vco:parameters>
</vco:execution-context>
“魔法线”# encoding: UTF-8
告诉 Ruby,脚本中的字符编码是 UTF-8。还有其他可用的编码。在 Ruby v2.0 之前,它假定内容是 ASCII。v2.0+ 采用 UTF-8。
在运行时,Nokogiri 也会假设,直到它尝试解析文档。如果 XML 声明指定了一个字符集,Nokogiri 会假定信息是正确的,并且 XML 中的所有字符都将匹配该信息。XML 是一个严格的规范,因此编码必须与输入的实际字符字节匹配。
在上面的示例中,我告诉 Ruby 和 Nokogiri,我使用的是 UTF-8。XML 文档的声明说它是Win-1251
. 因为我使用基于 UTF-8 的系统并粘贴 UTF-8 内容,所以我告诉 Nokogiri 改变对文档编码的理解,方法是使用doc.encoding = "UTF-8"
使所有内容保持同步。之后,因为 Ruby、粘贴的字符串和 Nokogiri 一致,所以生成的 XML 将被正确编码。
这很重要的原因是因为必须正确编码某些字符才能使 XML 有效。根据规范,嵌入式标签(通常是 Unicode 字符)不能以原始形式粘贴到文档中,因此 Nokogiri 将它们转换为正确的编码。
尝试手动为一个非常简单的文档执行此操作很容易。随着文档的复杂性增加,或者插入的文本变长,问题会迅速增加。