【问题标题】:Nokogiri: controlling element prefix for new child elmentsNokogiri:控制新子元素的元素前缀
【发布时间】:2012-03-07 10:32:23
【问题描述】:

我有一个这样的 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>

如何为这些新的子元素设置元素名称的前缀?谢谢, 欧根

【问题讨论】:

    标签: ruby xml namespaces nokogiri prefix


    【解决方案1】:

    (删除了关于定义命名空间的部分,与问题正交并在编辑中修复)

    只需在代码中添加几行,即可获得所需的结果:

    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>
    

    【讨论】:

    • 谢谢。那工作得很好。我已经更正了原始帖子中的示例以包含正确的命名空间定义。干杯
    【解决方案2】:

    命名空间“foo”未定义。

    更多详情请看这里: Nokogiri/Xpath namespace query

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-21
      • 1970-01-01
      • 2010-11-29
      • 2015-06-02
      • 2015-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多