【问题标题】:Groovy: how to insert a node at the beginning of a list of elements in XML read in using XMLSlurper()Groovy:如何在使用 XMLSlurper() 读取的 XML 中元素列表的开头插入节点
【发布时间】:2011-06-29 19:14:57
【问题描述】:

我可能遗漏了一些明显的东西,因为我是 Groovy 的菜鸟,但我已经搜索过但没有找到我正在寻找的东西。我有一个测试类,我正在阅读一些 XML;我想在一系列元素的开头插入一个元素。我已经想出了如何替换第一个元素,我已经想出了如何追加一个节点到列表的末尾,但我似乎无法了解如何在列表的开头(或者理想情况下,任意位置)插入元素。

例如:

@Test
void foo()
{
    def xml = """<container>
                   <listofthings>
                       <thing id="100" name="foo"/>
                   </listofthings>
                 </container>"""

    def root = new XmlSlurper().parseText(xml)
    root.listofthings.thing[0].replaceNode ( { thing(id:101, name:'bar') })
    root.listofthings.appendNode  ( { thing(id:102, name:'baz') })

    def outputBuilder = new groovy.xml.StreamingMarkupBuilder()
    String result = outputBuilder.bind { mkp.yield root }
    print result
}

产生:

<container>
   <listofthings>
     <thing id='101' name='bar'/>
     <thing id='102' name='baz'/>
   </listofthings>
</container>

我真正想要的是在 listofthingsbeginning 处插入一个节点,即替换对 replaceNode 的调用的东西在 id 为 100 的东西之前插入 id 为 101 的东西。如果说我有一个更长的列表,在第 n 个元素之后插入一个节点,我也会很好。

(顺便说一句,有没有办法以更易读的格式获取输出?StreamingMarkupBuilder 的输出都以单行文本结束;为了清楚起见,我在上面重新格式化了)

编辑:我使用的是 1.7.5,它与 Eclipse 捆绑在一起,如果重要的话。

【问题讨论】:

    标签: xml groovy


    【解决方案1】:

    您可以通过将thing 元素从原始 xml 中提取到一个列表中,操作该列表,然后使用这个新列表重建文档来实现此目的:

    // function to take a single line xml output, and make it pretty
    String renderFormattedXml( String xml ){
      def stringWriter = new StringWriter()
      def node = new XmlParser().parseText( xml )
      new XmlNodePrinter( new PrintWriter( stringWriter ) ).print( node )
      stringWriter.toString()
    }
    
    def xml = """<container>
                   <listofthings>
                       <thing id="100" name="foo"/>
                   </listofthings>
                 </container>"""
    
    def root = new XmlSlurper().parseText(xml)
    
    def things = root.listofthings*.thing
    
    // Insert one at pos 0
    things.add( 0, { thing( id:98, name:'tim' ) } )
    
    // And one at the end
    things.add( { thing( id:999, name:'zebra' ) } )
    
    // And one at position 1
    things.add( 1, { thing( id:99, name:'groovy' ) } )
    
    def outputBuilder = new groovy.xml.StreamingMarkupBuilder()
    String result = outputBuilder.bind {
      container {
        listofthings {
          mkp.yield things
        }
      }
    }
    println renderFormattedXml( result )
    

    打印出来的

    <container>
      <listofthings>
        <thing id="98" name="tim"/>
        <thing id="99" name="groovy"/>
        <thing id="100" name="foo"/>
        <thing id="999" name="zebra"/>
      </listofthings>
    </container>
    

    【讨论】:

    • 太棒了!非常感谢!
    • 当我尝试运行上面的代码时,我在输出中得到了名称 =foo 和 id =100 的反转。为什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    相关资源
    最近更新 更多