2012-01-18 53 views
1

我正在解析一個docx文件並且出現錯誤:「未定義的命名空間前綴」。爲了解決這個問題,我決定定義名稱空間,它不存在於根標籤中。將屬性添加到已存在的XML文件中的xml標記

爲了做到這一點,我需要在根標記中插入一個「(url)」值的「xmlns:wp」屬性。

我該如何使用Nokogiri寶石來做到這一點?

或者如果更容易與其他寶石,只是告訴我如何。我使用此代碼將屬性添加到XML元素中:

doc = Nokogiri::XML(File.open(path_to_file) 
doc.xpath('w:document').each do |document| 
    document.set_attribute('xmlns:wp', 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing') 
end 

並獲取具有添加屬性的新元素。然後我可以重寫整個文件,但也許有另一種方法來解決我的問題?

+0

請提供一個小的示例XML文件和產生此錯誤的代碼。 – Phrogz 2012-01-18 20:15:56

回答

1

你需要提供更多關於你在做什麼導致錯誤的細節。只解析一個XML文檔不會讓Nokogiri拋出該錯誤;這反而忽略和丟棄的命名空間不聲明:

require 'nokogiri' 

# Here's a valid namespace used on an element: 
doc = Nokogiri.XML("<root xmlns:a='hi'><a:foo/></root>") 
puts doc.root 
#=> <root xmlns:a="hi"> 
#=> <a:foo/> 
#=> </root> 

# Here's a namespace that gets ignored 
doc = Nokogiri.XML("<root xmlns:a='hi'><zzz:foo/></root>") 
puts doc 
#=> <root xmlns:a="hi"> 
#=> <foo/> 
#=> </root> 

p doc.at('foo').namespace 
#=> nil 

# It's OK to declare namespaces later on 
doc = Nokogiri.XML("<root><kid xmlns:zzz='yo'><zzz:foo/></kid></root>") 
puts doc.root 
#=> <root> 
#=> <kid xmlns:zzz="yo"> 
#=>  <zzz:foo/> 
#=> </kid> 
#=> </root> 

解析使用那些從未宣佈過無可挽回地失去他們的命名空間的XML文檔。因此,即使您可以在任何節點上設置屬性,像這樣...

mynode["xmlns:yay"]="someurl" 

...它不會幫助您已解析的引用該名稱空間名稱的節點。

現在,也許你的問題是,你正在通過稍後聲明的命名空間搜索節點?

p doc.at_xpath('//zzz:foo') 
#=> in `evaluate': Undefined namespace prefix: //zzz:foo (Nokogiri::XML::XPath::SyntaxError) 

如果是這樣,你必須告訴引入nokogiri關於命名空間:

p doc.at_xpath('//zzz:foo','zzz'=>'yo') 
#=> #<Nokogiri::XML::Element:0x80691894 name="foo" namespace=#<Nokogiri::XML::Namespace:0x806917cc prefix="zzz" href="yo">> 

另外,如果你只解析文檔(不發射它後來由於XML),而你沒有有任何名稱衝突,你可以作弊,只是拋出所有命名空間更簡單的查詢:

p doc.at_xpath('//foo') 
#=> nil 

doc.remove_namespaces! 
p doc.at_xpath('//foo') 
#=> #<Nokogiri::XML::Element:0x805fa2dc name="foo"> 
+0

非常感謝,doc.at_xpath('// zzz:foo','zzz'=>'yo')的作品 – Hroft 2012-01-19 06:56:00

相關問題