使用Nokogiri检索XML名称空间

时间:2018-06-22 00:28:21

标签: ruby nokogiri

我正在使用下面的代码从下面显示的XML中检索ns2:Title标记的内容。

到目前为止我所拥有的:

results = Nokogiri::XML(search_results)
p results.xpath '//ns2:Title', 'ns2': 'http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd'

它可以工作,但是当XML文档中已经存在ns2名称空间URL时,我不希望明确提及它。但是我似乎无法从“产品”标签中检索到它。我尝试了p results.css('Products').attr('xmlns:n2')的变体,但无法完成工作,它只返回nil。如何获得Products标签的xmlns:n2属性值?

我的XML(为简化起见):

<?xml version="1.0"?>
<GetMatchingProductForIdResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
  <GetMatchingProductForIdResult Id="028023810000" IdType="UPC" status="Success">
    <Products xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01" xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd">
      <Product>
        <AttributeSets>
          <ns2:ItemAttributes xml:lang="en-US">
            <ns2:Studio>WECO Electrical Connectors Inc</ns2:Studio>
            <ns2:Title>Weco Wonder Shell Natural Minerals (3 Pack), Small</ns2:Title>
          </ns2:ItemAttributes>
        </AttributeSets>
        <Relationships>
          <VariationParent>
            <Identifiers>
              <MarketplaceASIN>
                <MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
                <ASIN>B077HQHBQ6</ASIN>
              </MarketplaceASIN>
            </Identifiers>
          </VariationParent>
        </Relationships>
        <SalesRankings>
          <SalesRank>
            <ProductCategoryId>pet_products_display_on_website</ProductCategoryId>
            <Rank>14863</Rank>
          </SalesRank>
        </SalesRankings>
      </Product>
    </Products>
  </GetMatchingProductForIdResult>
</GetMatchingProductForIdResponse>

1 个答案:

答案 0 :(得分:1)

cssxpath将返回NodeSet(请考虑Enumerable#select),但是您需要实际的Element本身。

为此,nokogiri提供了at_前缀的方法at_cssat_xpath,它们将返回第一个匹配的Element。实现非常简单

css(*args).first 

因此,为了获取名称空间,您需要使用以下两种方法之一,并且两者本质上都相同

 results.css('Products').first.namespaces['xmlns:ns2']
 #=> "http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd"
 results.at_css('Products').namespaces['xmlns:ns2']
 #=> "http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd"

但是,如果您唯一的目标是“ ns2:Title”元素,那么

results.xpath("//*[name() = 'ns2:Title']").text
#=> "Weco Wonder Shell Natural Minerals (3 Pack), Small"

另外,如果您只需要任何“标题”属性,并且名称空间不是必需的,那么

results.xpath("//*[local-name() ='Title']").text
#=> "Weco Wonder Shell Natural Minerals (3 Pack), Small"