【问题标题】:Displaying XML nodes with Nokogiri in Rails view在 Rails 视图中使用 Nokogiri 显示 XML 节点
【发布时间】:2011-11-10 18:34:28
【问题描述】:

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

我想知道是否有人有一种简单的方法可以在同样包含非 XML 内容的 Rails 视图中显示这些结果。

我研究过 XSLT,但对它了解得不够多,尤其是与 Rails 无关,不知道我是否应该花时间在这方面。如果是这样,我会喜欢一些关于如何在 Rails 视图中使用 XSLT 的指示。

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

正如您将在“XML Schema”中看到的那样,并非所有的“sdnEntry”项都具有相同的元素。因此,我想显示有关每个“sdnEntry”的以下信息,并在适用的情况下省略任何空元素。

请随时在 cmets 中提问。非常感谢您的帮助。

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

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

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

【问题讨论】:

  • 当您说“在 Rails 视图中显示这些结果”时,您的意思是要以“漂亮”格式显示原始 XML,例如 this image?如果是这样,语法着色重要吗?还是您的意思是您想从 XML 中提取信息并以漂亮的格式显示(例如,作为 <dl>/<dt><dd> 列表自定义标记和格式化)?如果是这样,您是否需要通用解决方案(任何 XML sn-p)或针对您获得的特定结果量身定制的解决方案?
  • 我不知道你在倒数第二段中的意思是什么,“我想显示有关每个'sdnEntry'的以下信息”。您是否打算提供要显示的特定元素的列表?或者你是说即使没有特定的子元素(例如,如果 <firstName> 被合法省略)你仍然想在输出中包含一个空元素?
  • 您忘记提供所需的输出(我希望所提供的链接指向 XML 文档)。
  • 在上面的编辑中提供了响应。

标签: ruby-on-rails xml xslt nokogiri


【解决方案1】:

你仍然没有提供足够的细节来告诉我你真正想要什么,让我给你一个好的答案,但你已经给出了足够的答案来得到一个的答案。 :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>

【讨论】:

  • 虽然我缺乏知识意味着我显然没有以一种允许您以您想要的方式回答问题的方式提出问题,但您的回答正好符合我的目的。它给了我足够的信息来整理其余部分。为此,我感谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 2014-01-12
相关资源
最近更新 更多