Hroft
Hroft

Reputation: 4187

Get value of XML attribute with namespace

I'm parsing a pptx file and ran into an issue. This is a sample of the source XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  <p:sldMasterIdLst>
    <p:sldMasterId id="2147483648" r:id="rId2"/>
  </p:sldMasterIdLst>
  <p:sldIdLst>
    <p:sldId id="256" r:id="rId3"/>
  </p:sldIdLst>
  <p:sldSz cx="10080625" cy="7559675"/>
  <p:notesSz cx="7772400" cy="10058400"/>
</p:presentation>

I need to to get the r:id attribute value in the sldMasterId tag.

doc = Nokogiri::XML(path_to_pptx)
doc.xpath('p:presentation/p:sldMasterIdLst/p:sldMasterId').attr('id').value

returns 2147483648 but I need rId2, which is the r:id attribute value.

I found the attribute_with_ns(name, namespace) method, but

doc.xpath('p:presentation/p:sldMasterIdLst/p:sldMasterId').attribute_with_ns('id', 'r')

returns nil.

Upvotes: 3

Views: 1304

Answers (2)

matt
matt

Reputation: 79723

You can reference the namespace of attributes in your xpath the same way you reference element namespaces:

doc.xpath('p:presentation/p:sldMasterIdLst/p:sldMasterId/@r:id')

If you want to use attribute_with_ns, you need to use the actual namespace, not just the prefix:

doc.at_xpath('p:presentation/p:sldMasterIdLst/p:sldMasterId')
  .attribute_with_ns('id', "http://schemas.openxmlformats.org/officeDocument/2006/relationships")

Upvotes: 2

Eugene Rourke
Eugene Rourke

Reputation: 4934

http://nokogiri.org/Nokogiri/XML/Node.html#method-i-attributes

If you need to distinguish attributes with the same name, with different namespaces use attribute_nodes instead.

doc.xpath('p:presentation/p:sldMasterIdLst/p:sldMasterId').each do |element| 
  element.attribute_nodes().select do |node|
    puts node if node.namespace && node.namespace.prefix == "r"
  end  
end

Upvotes: 0

Related Questions