ruby
  • xml
  • rest
  • 2013-05-22 1 views 1 likes 
    1

    Мне нужно передать в приложение, которое использует параметры API REST в следующих XML-файлКак вставить XML в другой XML-файл (REST API)

    paramValue = "<tag><stillonetag>value</stillonetag></tag>" 
    xmlIn = ' 
    <?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>#{paramValue}</vco:string> 
         </vco:parameter> 
         </vco:parameters> 
    </vco:execution-context> 
    ' 
    xmlExec = xmlIn.gsub(/\>[\s\n\r]+\</, '><') 
    response = HTTParty.post("/workflows/#{id}/presentation/instances/", { :basic_auth => @auth, :body => xmlExec}) 
    

    с «нормальными» строк У меня нет никаких проблем, однако в этом случае параметр inputXML ожидает значение как XML-строку. Как встроить такую ​​строку XML в константу ruby ​​выше? Большое спасибо заранее.

    +0

    Возможно, вы можете попробовать обратный слэш \ – vkrams

    +0

    Ну, @Vikram я уже пытался бежать> и <с backslashes_but без успеха :( –

    +0

    Вставить его как CDATA? Или как фактический узел? – pguardiario

    ответ

    0

    Правило 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>&lt;tag&gt;&lt;stillonetag&gt;value&lt;/stillonetag&gt;&lt;/tag&gt;</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>&lt;operation&gt;информация&lt;/operation&gt;</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 преобразует их в правильную кодировку.

    Попытка сделать это вручную для очень простого документа легко. По мере того как сложность документа увеличивается, или вставленный текст увеличивается, проблема быстро растет.

    +0

    Привет, @theTinMan, спасибо большое, но проблема не в том, что я не могу правильно вставить текст в переменную. Проблема в том, что текст XML не распознается –

    +0

    Вы действительно не дали нам достаточно для работы. ЧТО «XMLin» вы хотите вставить? Что означает «XMLin2», используемый для вашего кода? Что значит «не распознано»? «По другую сторону вы его отправляете? Является ли XML, который вы генерируете недействительным? Мы можем помочь вам только в том случае, если вы объясните, что происходит. п. –

    +0

    Привет, @theTinMan цель очень проста - мне нужно передать внутри XML-объекта (xmlIn) между строку, содержащую объект XML (paramValue), но не должна интерпретироваться как XML-текст движком REST. Механизм REST должен анализировать текст xmlIn и передавать параметр и его значение в прикладную программу. И прикладная программа sjhould, в свою очередь, анализирует остальную часть XML.Когда я использую Nokogiri, я получаю объект XML, а моя встроенная часть интерпретируется как часть внешнего XML-объекта. –

    0

    GOT IT !!!! передать текст XML в качестве значения для XML-тег внутри другого объекта XML, не делает его частью этого объекта

    I need to use &lt; and &gt; instead of <and>. 
    

    В моем примере это должно быть

    paramValue = "&lt;tag>&lt;stillonetag&gt;value&lt;/stillonetag&gt;&lt;/tag&gt;" 
    

    Так долго, эксперты XML!

    +0

    Если вам нужно внедрить XML в виде закодированного текста, тогда легко сделайте это с помощью синтаксического анализатора, так что все еще сделано правильно. См. Изменение в моем ответе. Знание того, какой символ кодируется, встроен в Nokogiri, а также возможность использования разделов CDATA, если HTML-кодирование тегов недостаточно или желательно. –

    +0

    @theTinMan Ну, с моей точки зрения, лучше иметь простое решение, которое работает, чем гениальное и сложное (nokogiri), которое не работает. Мне нужно использовать кириллические буквы в XML, но когда я пытаюсь docExCon.at ('// vco: string') .content = ' информация' Я получаю ошибку кодирования: выходное преобразование не удалось из-за ошибки conv, байты 0xE8 0xED 0xF4 0xEE Ошибка ввода-вывода: ошибка кодировщика, поэтому мне нужно полностью переписать свой код с нуля, используя что-то менее блестящее, что nokogiri, но работает ;-) –

    +0

    Нет, проблема не в Nokogiri, это ваше понимание того, как Ruby обрабатывает многобайтовые символы. Nokogiri полностью поддерживает UTF-8 и Unicode, чтобы правильно обрабатывать XML, но он ожидает, что вы все сделаете правильно. Вы не хотите, чтобы Ruby жаловался. Вы продолжаете добавлять новые условия и требования к своему вопросу, а не представлять их с самого начала. Я думаю, вы решили, что знаете ответ и не хотите изучать правильный способ справиться с этим. Удачи. Это будет ухабистая поездка. –

     Смежные вопросы

    • Нет связанных вопросов^_^