Groovy:如何在使用XMLSlurper()读入的XML元素列表的开头插入一个节点

Eri*_*rry 5 xml groovy

我可能错过了一些显而易见的东西,因为我是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
}
Run Code Online (Sandbox Code Playgroud)

产量:

<container>
   <listofthings>
     <thing id='101' name='bar'/>
     <thing id='102' name='baz'/>
   </listofthings>
</container>
Run Code Online (Sandbox Code Playgroud)

我真正想要的是在插入点开始listofthings,即东西来取代调用replaceNode将ID为100之前的事情,而不是插入一个ID为101的事情,我也将是如果说不好听,我有一个更长的列表,在第n个元素之后插入一个节点.

(顺便提一下,有没有办法以更易读的格式获取输出?StreamingMarkupBuilder的输出都以一行文本结尾;为了清楚起见,我重新格式化了它)

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

tim*_*tes 7

有一种方法可以通过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 )
Run Code Online (Sandbox Code Playgroud)

打印

<container>
  <listofthings>
    <thing id="98" name="tim"/>
    <thing id="99" name="groovy"/>
    <thing id="100" name="foo"/>
    <thing id="999" name="zebra"/>
  </listofthings>
</container>
Run Code Online (Sandbox Code Playgroud)