使用Nokogiri xpath(使用xml namesapce)在xml中搜索节点

icn*_*icn 4 ruby xpath xml-namespaces nokogiri

我发现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>
Run Code Online (Sandbox Code Playgroud)

当我做的时候

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

我得到了空节点.我错过了什么?我试过了

 nodes = doc.search("//Configuration\.Store")
Run Code Online (Sandbox Code Playgroud)

仍然没有运气.

更新:我已附加整个xml文件

再次更新了xml:我的错误,它确实有一个namaspace

Eze*_*lin 5

编辑#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
Run Code Online (Sandbox Code Playgroud)