在Rails视图中使用Nokogiri显示XML节点

时间:2011-11-10 18:34:29

标签: ruby-on-rails xml xslt nokogiri

因此,使用我之前的“question”中的建议,我已经能够得到我想要的结果。

我想知道是否有人能够轻松地在Rails视图中显示这些结果,该视图也包含非XML内容。

我已经研究过XSLT但是对它没有足够的了解,尤其是与Rails无关,要知道这是否应该花费我的时间。如果是这样,我想了解如何在Rails视图中使用XSLT。

我正在寻找的是显示“sdnEntry”结果列表(有关详细信息,请参阅“XML Schema”。)

正如您将从'XML Schema'看到的,并非所有'sdnEntry'项目都具有相同的元素。因此,我想显示有关每个'sdnEntry'的以下信息,省略任何适用的空元素。

请随时在评论中提问。我非常感谢你的帮助。

编辑#1:可以找到XML文件here。 (6MB)

编辑#2:我更喜欢<dl>/<dt><dd>列表。哎呀,我甚至会选择一张普通的旧桌子。至于空元素,您将从模式中看到,某些子元素(如'firstName'或'address3'等)的最小出现次数为0,因此找不到每个'sdnEntry'。如果可能的话,我宁愿不显示空白子元素。如果这是一个问题,如果需要的话,我最终可以使用空白。

编辑#3:结果将始终是一个或多个“sdnEntry”项目的Nokogiri NodeSet。这就是我需要展示的全部内容。我相信,只要有足够的指导或示例代码,我就可以将任何提供的解决方案应用于其他需求。

1 个答案:

答案 0 :(得分:3)

你仍然没有提供足够的细节来说明你真正希望我给你一个好的答案,但你已经给予了足够的 答案。 :P

下面显示了如何将XML文件加载到Nokogiri文档中,创建一个Haml模板(这将是您的Rails视图的一部分;如果您使用的是Erb或其他模板系统,请说明) sdnEntry的列表,并执行所有XML的完全天真的大量转储。如果你想要特定的节点,那么你应该这么说。

require 'nokogiri'
require 'haml'

# Haml helper to create a naive hierarchy of dl/dt/dd for any xml node
def xml_to_dl(node)
  haml_tag('dl') do
    node.elements.each do |n|
      haml_tag('dt',n.name)
      if n.elements.empty?
        haml_tag('dd',n.text)
      else
        haml_tag('dd'){ xml_to_dl(n) }
      end
    end
  end
end

# This would be your page.haml view
template = Haml::Engine.new <<'ENDHAML'
%section#sdnList
  %h1#sdnList SDN List Awesomeness
  - if @sdns.empty?
    %p.error No entries found. :(
  - else
    %p Here are some exciting sdnEntries. Check em out!
    - @sdns.each do |sdn|
      %h2.name #{sdn.at('lastName').text}, #{sdn.at('firstName').text}
      - xml_to_dl(sdn)
ENDHAML

# This would be in your controller
doc  = Nokogiri.XML(IO.read('sdn.xml'))
doc.remove_namespaces! # Make life easier
@sdns = doc.xpath('/sdnList/sdnEntry[firstName][position() < 2]')

# This is taken care of by rails
puts template.render(self)

这是特定模板将创建的输出:

<section id='sdnList'>
  <h1 id='sdnList'>SDN List Awesomeness</h1>
  <p>Here are some exciting sdnEntries. Check em out!</p>
  <h2 class='name'>GONZALEZ BOHORQUEZ, Guillermo</h2>
  <dl>
    <dt>uid</dt>
    <dd>11764</dd>
    <dt>firstName</dt>
    <dd>Guillermo</dd>
    <dt>lastName</dt>
    <dd>GONZALEZ BOHORQUEZ</dd>
    <dt>sdnType</dt>
    <dd>Individual</dd>
    <dt>programList</dt>
    <dd>
      <dl>
        <dt>program</dt>
        <dd>SDNT</dd>
      </dl>
    </dd>
    <dt>idList</dt>
    <dd>
      <dl>
        <dt>id</dt>
        <dd>
          <dl>
            <dt>uid</dt>
            <dd>6139</dd>
            <dt>idType</dt>
            <dd>Cedula No.</dd>
            <dt>idNumber</dt>
            <dd>6185654</dd>
            <dt>idCountry</dt>
            <dd>Colombia</dd>
          </dl>
        </dd>
        <dt>id</dt>
        <dd>
          <dl>
            <dt>uid</dt>
            <dd>6140</dd>
            <dt>idType</dt>
            <dd>Passport</dd>
            <dt>idNumber</dt>
            <dd>AJ772175</dd>
            <dt>idCountry</dt>
            <dd>Colombia</dd>
          </dl>
        </dd>
      </dl>
    </dd>
    <dt>addressList</dt>
    <dd>
      <dl>
        <dt>address</dt>
        <dd>
          <dl>
            <dt>uid</dt>
            <dd>17790</dd>
            <dt>address1</dt>
            <dd>c/o UNIVISA S.A.</dd>
            <dt>city</dt>
            <dd>Cali</dd>
            <dt>country</dt>
            <dd>Colombia</dd>
          </dl>
        </dd>
      </dl>
    </dd>
    <dt>dateOfBirthList</dt>
    <dd>
      <dl>
        <dt>dateOfBirthItem</dt>
        <dd>
          <dl>
            <dt>uid</dt>
            <dd>7272</dd>
            <dt>dateOfBirth</dt>
            <dd>20 Dec 1944</dd>
            <dt>mainEntry</dt>
            <dd>true</dd>
          </dl>
        </dd>
      </dl>
    </dd>
    <dt>placeOfBirthList</dt>
    <dd>
      <dl>
        <dt>placeOfBirthItem</dt>
        <dd>
          <dl>
            <dt>uid</dt>
            <dd>7273</dd>
            <dt>placeOfBirth</dt>
            <dd>Buga, Valle, Colombia</dd>
            <dt>mainEntry</dt>
            <dd>true</dd>
          </dl>
        </dd>
      </dl>
    </dd>
  </dl>
</section>