How to save unescaped & in nokogiri xml?

后端 未结 1 1486
余生分开走
余生分开走 2020-12-22 06:50

How can I save & in the final xml file using nokogiri?

My code is like:

require \'rubygems\' 
require \'nokogiri\'

  file_name = \"         


        
相关标签:
1条回答
  • 2020-12-22 07:12

    You can't put an unescaped & in XML as you wish. Here is from the W3 spec for XML:

    The ampersand character (&) and the left angle bracket (<) MUST NOT appear in their literal form, except when used as markup delimiters, or within a comment, a processing instruction, or a CDATA section. If they are needed elsewhere, they MUST be escaped using either numeric character references or the strings " & " and " < " respectively.

    As for using CDATA in Nokogiri, here is info from Nokogiri's site, if you use Nokogiri::XML::Builder to build your XML.

    UPDATE: Here is the code from my example mentioned in comments.

    module Questions
      @source = File.dirname(__FILE__) + '/questions.xml'
      def parse
        if File.exists?(@source)
          File.open(@source, 'r+') do |document|
            q = {}
            text = Nokogiri::XML::Document.parse(document)
            text.xpath('.//question').each do |c|
              parent = c.attribute_nodes[2].to_s
              q[:type] = c.attribute_nodes[1].to_s.to_sym   # => question type
              q[:q_id] = c.attribute_nodes[0].to_s   # => question type
              q[:question] = c.xpath('.//q').first.content   # => question
              q[:answers] = []
              c.xpath('.//a').each { |ans|
                p = ans.attribute_nodes.first.value   # => point value
                a = ans.content   # => answer
                q[:answers] << [a, p]
              }
              if parent == "NA"
                Question.create!(q)
              else
                Question.first(conditions: {q_id: parent}).children << Question.create!(q)
              end
            end
          end
        end
      end
    
      def write
        builder = Nokogiri::XML::Builder.new do |xml|
          xml.root {
            Question.each do |t|
              xml.question(id: t.id, type: t.type, parent: t.parent) {
                xml.q_ t.q
                t.answers.each { |c|
                  xml.a(point: c.p) { xml.text c.a }
                }
              }
            end
          }
        end
        document = builder.to_xml
        File.open(@source, 'w+') do |f|
          f.puts document
        end
      end   # end write
    
      module_function :parse
      module_function :write
    end
    

    --- And an example of what I was working with. ---

      <question id="q0000" type="root" parent="NA">
        <q>How do you feel about sports?</q>
        <a point="0">I don't have any interest in sports.</a>
        <a point="q0001">I like to play sports.</a>
        <a point="q0002">I follow college or professional sports.</a>
      </question>
    
    0 讨论(0)
提交回复
热议问题