Правило 1: НЕ пытайтесь обрабатывать 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>
EDIT:
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
говорит Руби, что тя racter-кодировка в скрипте - UTF-8. Существуют и другие кодировки. До Ruby v2.0 он предполагал, что контент был ASCII. v2.0 + предполагает UTF-8.
Во время выполнения Nokogiri будет считать это слишком, пока он не попытается разобрать документ. Если объявление XML указывает набор символов, Nokogiri предполагает, что информация верна и что все символы в XML будут соответствовать этому. XML - строгая спецификация, поэтому кодировка должна соответствовать введенным фактическим байтам.
В приведенном выше примере я сказал Руби и Нокогири, что я использую UTF-8. В заявлении документа XML говорится, что это Win-1251
. Поскольку я использую систему на основе UTF-8 и вставляю содержимое UTF-8, я сказал Nokogiri изменить свое понимание кодировки документа, используя doc.encoding = "UTF-8"
, чтобы получить все в синхронизации. После этого, поскольку Ruby, вставленная строка и Nokogiri согласуются, полученный XML будет правильно закодирован.
Причина, по которой это важно, состоит в том, что некоторые символы должны быть закодированы правильно, чтобы XML был действительным. Встроенные теги и часто символы Unicode не могут застревать в документе в необработанном виде по спецификации, поэтому Nokogiri преобразует их в правильную кодировку.
Попытка сделать это вручную для очень простого документа легко. По мере того как сложность документа увеличивается, или вставленный текст увеличивается, проблема быстро растет.
Возможно, вы можете попробовать обратный слэш \ – vkrams
Ну, @Vikram я уже пытался бежать> и <с backslashes_but без успеха :( –
Вставить его как CDATA? Или как фактический узел? – pguardiario