Поиск узла в xml с помощью Nokogiri xpath (с xml namesapce) - PullRequest
4 голосов
/ 07 января 2012

Я обнаружил, что Nokogiri достаточно силен в работе с XML, но я встретил особый случай

Я пытаюсь найти узел в файле XML, как это

     <?xml version="1.0" encoding="utf-8" ?>
     <ConfigurationSection>
      <Configuration xmlns="clr-namespace:Newproject.Framework.Server.Store.Configuration;assembly=Newproject.Framework.Server" >
       <Configuration.Store>SqlServer</Configuration.Store>
       <Configuration.Engine>Staging</Configuration.Engine>
      </Configuration>
   </ConfigurationSection>

Когда я делаю

xml = File.new(webconfig,"r")
doc = Nokogiri::XML(xml.read)
nodes = doc.search("//Configuration.Store")
xml.close

Я получил пустые узлы.Что-то мне не хватает?Я пытался

 nodes = doc.search("//Configuration\.Store")

все еще не повезло.

Обновлено: я приложил весь XML-файл

Обновлен XML-файл Еще раз: Моя ошибка, у него есть namaspace

Ответы [ 2 ]

5 голосов
/ 07 января 2012

РЕДАКТИРОВАТЬ # 2: решение теперь включает #parse_with_namespace

В документации Nokogiri :: XML :: Node .

можно найти ряд методов Nokogiri, относящихся к пространствам имен.
# encoding: UTF-8
require 'rspec'
require 'nokogiri'

XML = <<XML
<?xml version="1.0" encoding="utf-8" ?>
  <ConfigurationSection>
   <Configuration xmlns="clr-namespace:Newproject.Framework.Server.Store.Configuration;assembly=Newproject.Framework.Server" >
    <Configuration.Store>SqlServer</Configuration.Store>
    <Configuration.Engine>Staging</Configuration.Engine>
   </Configuration>
</ConfigurationSection>
XML


class ConfigParser
  def parse(xml)
    doc = Nokogiri::XML(xml).remove_namespaces!
    configuration = doc.at('/ConfigurationSection/Configuration')
    store   = configuration.at("./Configuration.Store").text
    engine  = configuration.at("./Configuration.Engine").text
    {store: store, engine: engine}
  end

  def parse_with_namespace(xml)
    doc = Nokogiri::XML(xml)
    configuration = doc.at('/ConfigurationSection/xmlns:Configuration', 'xmlns' => 'clr-namespace:Newproject.Framework.Server.Store.Configuration;assembly=Newproject.Framework.Server')
    store   = configuration.at("./xmlns:Configuration.Store", 'xmlns' => 'clr-namespace:Newproject.Framework.Server.Store.Configuration;assembly=Newproject.Framework.Server').text
    engine  = configuration.at("./xmlns:Configuration.Engine", 'xmlns' => 'clr-namespace:Newproject.Framework.Server.Store.Configuration;assembly=Newproject.Framework.Server').text
    {store: store, engine: engine}
  end
end

describe ConfigParser do
  before(:each) do
    @parsed         = subject.parse XML
    @parsed_with_ns = subject.parse_with_namespace XML
  end

  it "should be able to parse the Configuration Store" do
    @parsed[:store].should eq "SqlServer"
  end

  it "should be able to parse the Configuration Engine" do
    @parsed[:engine].should eq "Staging"
  end

  it "should be able to parse the Configuration Store with namespace" do
    @parsed_with_ns[:store].should eq "SqlServer"
  end

  it "should be able to parse the Configuration Engine with namespace" do
    @parsed_with_ns[:engine].should eq "Staging"
  end
end
0 голосов
/ 07 января 2012
require 'nokogiri'
XML = "<Configuration>
  <Configuration.Store>SqlServer</Configuration.Store>
  <Configuration.Engine>Staging</Configuration.Engine>
</Configuration>"
p Nokogiri::VERSION, Nokogiri.XML(XML).search('//Configuration.Store')
#=> "1.5.0"
#=> [#<Nokogiri::XML::Element:0x8103f0f8 name="Configuration.Store" children=[#<Nokogiri::XML::Text:0x81037524 "SqlServer">]>]

p RUBY_DESCRIPTION
#=> "ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.7.0]"
...