Nokogiri: управляющий префикс элемента для новых дочерних элементов - PullRequest
2 голосов
/ 16 февраля 2012

У меня есть XML-документ, подобный этому:

<?xml version="1.0" encoding="UTF-8"?>
<foo:root xmlns:foo="http://abc.com#" xmlns:bar="http://def.com" xmlns:ex="http://ex.com">
  <foo:element foo:attribute="attribute_value">
    <bar:otherElement foo:otherAttribute="otherAttributeValue"/>
  </foo:element>
</foo:root>

Мне нужно добавить дочерние элементы к элементу, чтобы он выглядел так:

<?xml version="1.0" encoding="UTF-8"?>
<foo:root xmlns:foo="http://abc.com#" xmlns:bar="http://def.com" xmlns:ex="http://ex.com">
  <foo:element foo:attribute="attribute_value">
    <bar:otherElement foo:otherAttribute="otherAttributeValue"/>
    <bar:otherElement foo:otherAttribute="newAttributeValue"/>
    <ex:yetAnotherElement foo:otherAttribute="yetANewAttributeValue"/>
  </foo:element>
</foo:root>

Я могу добавить элементы вправильное местоположение, используя следующее:

require 'rubygems'
require 'nokogiri'
doc = Nokogiri::XML::Document.parse(File.open("myfile.xml"))
el = doc.at_xpath('//foo:element')

newEl = Nokogiri::XML::Node.new("otherElement", doc)            
newEl["foo:otherAttribute"] = "newAttributeValue"
el.add_child(newEl)

newEl = Nokogiri::XML::Node.new("yetAnotherElement", doc)           
newEl["foo:otherAttribute"] = "yetANewAttributeValue"
el.add_child(newEl)

Однако префикс новых элементов всегда "foo":

<foo:root xmlns:foo="http://abc.com#" xmlns:bar="http://def.com" xmlns:ex="http://ex.com">
  <foo:element foo:attribute="attribute_value">
    <bar:otherElement foo:otherAttribute="otherAttributeValue" /> 
    <foo:otherElement foo:otherAttribute="newAttributeValue" /> 
    <foo:yetAnotherElement foo:otherAttribute="yetANewAttributeValue" /> 
  </foo:element>
</foo:root>

Как мне установить префикс для имени элемента для этихновые дочерние элементы?Спасибо, Эоган

Ответы [ 2 ]

3 голосов
/ 16 февраля 2012

(удален бит об определении пространства имен, ортогональный к вопросу и исправленный при редактировании)

просто добавьте несколько строк в ваш код, и вы получите желаемый результат:

require 'rubygems'
require 'nokogiri'
doc = Nokogiri::XML::Document.parse(File.open("myfile.xml"))
el = doc.at_xpath('//foo:element')

newEl = Nokogiri::XML::Node.new("otherElement", doc)            
newEl["foo:otherAttribute"] = "newAttributeValue"
# ADDITIONAL CODE
newEl.namespace = doc.root.namespace_definitions.find{|ns| ns.prefix=="bar"}
#
el.add_child(newEl)

newEl = Nokogiri::XML::Node.new("yetAnotherElement", doc)           
newEl["foo:otherAttribute"] = "yetANewAttributeValue"
# ADDITIONAL CODE
newEl.namespace = doc.root.namespace_definitions.find{|ns| ns.prefix == "ex"}
#
el.add_child(newEl)

и результат:

<?xml version="1.0" encoding="UTF-8"?>
<foo:root xmlns:abc="http://abc.com#" xmlns:def="http://def.com" xmlns:ex="http://ex.com" xmlns:foo="http://foo.com" xmlns:bar="http://bar.com">
  <foo:element foo:attribute="attribute_value">
    <bar:otherElement foo:otherAttribute="otherAttributeValue"/>
    <bar:otherElement foo:otherAttribute="newAttributeValue"/>
    <ex:yetAnotherElement foo:otherAttribute="yetANewAttributeValue"/>
  </foo:element>
</foo:root>
1 голос
/ 16 февраля 2012

Пространство имен 'foo' не определено.

См. Это для более подробной информации: Запрос пространства имен Nokogiri / Xpath

...