【问题标题】:How to convert an array of hashes into XML in Rails?如何在 Rails 中将哈希数组转换为 XML?
【发布时间】:2016-12-02 03:34:33
【问题描述】:

我有一个数据库对象数组@configs,我想将其转换为 XML 格式,但输出不是预期的。每个条目都包含在<map> 标记而不是<entry> 标记中,我只希望<tag> 成为XML 根。如何使用 <tag> 根构建 XML 并将所有条目放在 <entry> 标记中? 提前感谢您的帮助和时间!

这是我的代码:

    entries = Array.new
    entry = Hash.new
    conf = Hash.new  

    @configs.each do |config|

      entry.store('string', config.key)

      conf.store('value', config.value)
      conf.store('comment', config.comment)

      entry.store('com.mirth.connect.util.ConfigurationProperty', conf)

      entries << entry    

    end

    pp entries.to_xml(:root => 'map', :indent => 0, :skip_types => true)

结果是:

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<map>
    <map>
        <string>PNB_ALERTLOG_RECEIVER_CHANNEL</string>
        <com.mirth.connect.util.ConfigurationProperty>
            <value>PNB_ALERTLOG_RECEIVER</value>
            <comment>Canal que irá receber tudo o que for logged com Warning e Error</comment>
        </com.mirth.connect.util.ConfigurationProperty>
    </map>
    <map>
        <string>PNB_CFG_FILE_ACCESS_CONTROL</string>
        <com.mirth.connect.util.ConfigurationProperty>
            <value>resources/configPnbDev/pnbAccessControl.json</value>
            <comment>Este ficheiro permite configurar Autenticação e Controlo de Acessos.</comment>
        </com.mirth.connect.util.ConfigurationProperty>
    </map>
    <map>
        <string>PNB_CFG_FILE_CONNECTION_POOLS</string>
        <com.mirth.connect.util.ConfigurationProperty>
            <value>resources/configPnbDev/pnbConnectionPools.json</value>
            <comment>Configuração de Oracle Universal Connection Pools usadas pelo PNB (PEM, RCU2)</comment>
        </com.mirth.connect.util.ConfigurationProperty>
    </map>
    <map>
        <string>PNB_CFG_FILE_CSP_MC_EXCLUSIONS</string>
        <com.mirth.connect.util.ConfigurationProperty>
            <value>resources/configPnbDev/medCronExclusions/mcExclCurrentRevision.json</value>
            <comment>N/A</comment>
        </com.mirth.connect.util.ConfigurationProperty>
    </map>
    <map>
        <string>PNB_CFG_FILE_FACILITIES_ALIAS</string>
        <com.mirth.connect.util.ConfigurationProperty>
            <value>resources/configPnbDev/snsFacilitiesAlias.json</value>
            <comment>Mapa de alias do codigo das instituicoes do SNS.</comment>
        </com.mirth.connect.util.ConfigurationProperty>
    </map>
</map>

我想要什么:

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<map>
    <entry>
        <string>PNB_ALERTLOG_RECEIVER_CHANNEL</string>
        <com.mirth.connect.util.ConfigurationProperty>
            <value>PNB_ALERTLOG_RECEIVER</value>
            <comment>Canal que irá receber tudo o que for logged com Warning e Error</comment>
        </com.mirth.connect.util.ConfigurationProperty>
    </entry>
    <entry>
        <string>PNB_CFG_FILE_ACCESS_CONTROL</string>
        <com.mirth.connect.util.ConfigurationProperty>
            <value>resources/configPnbDev/pnbAccessControl.json</value>
            <comment>Este ficheiro permite configurar Autenticação e Controlo de Acessos.</comment>
        </com.mirth.connect.util.ConfigurationProperty>
    </entry>
    <entry>
        <string>PNB_CFG_FILE_CONNECTION_POOLS</string>
        <com.mirth.connect.util.ConfigurationProperty>
            <value>resources/configPnbDev/pnbConnectionPools.json</value>
            <comment>Configuração de Oracle Universal Connection Pools usadas pelo PNB (PEM, RCU2)</comment>
        </com.mirth.connect.util.ConfigurationProperty>
    </entry>
    <entry>
        <string>PNB_CFG_FILE_CSP_MC_EXCLUSIONS</string>
        <com.mirth.connect.util.ConfigurationProperty>
            <value>resources/configPnbDev/medCronExclusions/mcExclCurrentRevision.json</value>
            <comment>N/A</comment>
        </com.mirth.connect.util.ConfigurationProperty>
    </entry>
    <entry>
        <string>PNB_CFG_FILE_FACILITIES_ALIAS</string>
        <com.mirth.connect.util.ConfigurationProperty>
            <value>resources/configPnbDev/snsFacilitiesAlias.json</value>
            <comment>entrya de alias do codigo das instituicoes do SNS.</comment>
        </com.mirth.connect.util.ConfigurationProperty>
    </entry>
</map>

【问题讨论】:

    标签: ruby-on-rails ruby xml


    【解决方案1】:

    试试这个:

        pp entries.to_xml(:root => 'map', :children => 'entry', :indent => 0, :skip_types => true)
    

    来源:http://apidock.com/rails/Array/to_xml

    【讨论】:

      【解决方案2】:

      假设条目是以下哈希:

      entry = {
        a: “hello”,
        b: “goodbye”,
      }
      

      如果你写:

      entries = []
      entries << entry
      p entries
      

      那么输出是:

      [{:a => “hello”, {:b => “goodbye”}]
      

      所以如果你接着写:

      p entries.to_xml
      

      你认为“entry”这个词将如何出现在输出中?这有点像期待以下输出:

      x = 10
      y = 20
      puts x+y
      

      在某处包含字母“x”和“y”。

      根据数组的 to_xml() 文档:

      通过在每个元素上调用 to_xml 返回一个字符串。
      选项哈希向下传递。
      http://apidock.com/rails/Array/to_xml

      选项哈希向下传递的事实意味着,当您为数组上的 to_xml() 调用指定 {root: map} 时,&lt;map&gt; 将成为 xml 的根,而当调用 to_xml() 时每个数组元素都将使用选项{root: “map”} 调用该方法,这将导致每个数组元素被包装在&lt;map&gt; 标记中。例如:

      puts [{a: 10, b: 20}, {a: 100, b: 200}].to_xml({root: "map"})
      
      --output:--
      
      <?xml version="1.0" encoding="UTF-8"?>
      <map type="array">
        <map>
          <a type="integer">10</a>
          <b type="integer">20</b>
        </map>
        <map>
          <a type="integer">100</a>
          <b type="integer">200</b>
        </map>
      </map>
      

      嵌套的&lt;map&gt; 标记是 to_xml() 方法内置功能的副作用:如果在数组上调用 to_xml() 时为 :root 选项指定复数名称,例如“maps”,然后当 rails 转身并在数组的每个元素上调用 to_xml() 时,rails 将为 :root 选项指定单数“map”。这是有道理的,因为如果您在数组上调用 to_xml() 并将 :root 选项指定为“maps”,那么每个数组元素自然可能是一个“map”。当然,这不是你想要的。

      幸运的是,正如 mr_sudaca 指出的那样:

      默认情况下,root 子节点的名称是 root.singularize。您可以使用 :children option 更改它。
      http://apidock.com/rails/Array/to_xml

      结果,这段代码:

      require 'ostruct'
      
      configs = [
        OpenStruct.new(
          key: "PNB_ALERTLOG_RECEIVER_CHANNEL",
          value: "PNB_ALERTLOG_RECEIVER",
          comment: "Canal que...",
        ),
        OpenStruct.new(
          key: "PNB_CFG_FILE_ACCESS_CONTROL",
          value: "resources/configPnbDev/pnbAccessControl.json",
          comment: "Este ficheiro...",
        )
      ]
      
      entries = []
      
      configs.each do |config|
        entry = {}
        conf = {}
      
        entry.store('string', config.key)
      
        conf.store('value', config.value)
        conf.store('comment', config.comment)
      
        entry.store('com.mirth.connect.util.ConfigurationProperty', conf)
      
        entries << entry
      end
      
      p entries
      puts entries.to_xml(:root => 'map', children: "entry", :skip_types => true)
      

      产生输出:

      <?xml version="1.0" encoding="UTF-8"?>
      <map>
        <entry>
          <string>PNB_ALERTLOG_RECEIVER_CHANNEL</string>
          <com.mirth.connect.util.ConfigurationProperty>
            <value>PNB_ALERTLOG_RECEIVER</value>
            <comment>Canal que...</comment>
          </com.mirth.connect.util.ConfigurationProperty>
        </entry>
        <entry>
          <string>PNB_CFG_FILE_ACCESS_CONTROL</string>
          <com.mirth.connect.util.ConfigurationProperty>
            <value>resources/configPnbDev/pnbAccessControl.json</value>
            <comment>Este ficheiro...</comment>
          </com.mirth.connect.util.ConfigurationProperty>
        </entry>
      </map>
      

      在我看来,您的条目和配置哈希也存在一些问题,因为条目数组中的每个元素都将引用相同的条目和配置哈希,并且由于您的循环不断更改这些哈希,因此数组中的每个条目将引用包含循环中设置的最后一个键/值的哈希。

      【讨论】:

      • 非常感谢@7stud 的开导和详细解释,确实帮助我理解了to_xml()。感谢您的宝贵时间!
      猜你喜欢
      • 2011-05-08
      • 1970-01-01
      • 2015-11-26
      • 1970-01-01
      • 2019-10-27
      • 2019-05-23
      • 2012-10-29
      • 2010-12-11
      • 1970-01-01
      相关资源
      最近更新 更多