简体   繁体   English

如何使用Groovy在xml中插入/移动/删除节点?

[英]How to insert/move/delete nodes in xml with Groovy?

for example, I have the following xml document: 例如,我有以下xml文档:

def CAR_RECORDS = '''
    <records>
      <car name='HSV Maloo' make='Holden' year='2006'/>
      <car name='P50' make='Peel' year='1962'/>
      <car name='Royale' make='Bugatti' year='1931'/>
    </records>
'''

and I want to move the car "Royale" up to first one, and insert a new car just after car"HSV Maloo", the result would be: 我想把汽车“皇家”推到第一辆,并在汽车“HSV Maloo”之后插入一辆新车,结果将是:

'''
    <records>
      <car name='Royale' make='Bugatti' year='1931'/>
      <car name='HSV Maloo' make='Holden' year='2006'/>
      <car name='My New Car' make='Peel' year='1962'/>
      <car name='P50' make='Peel' year='1962'/>
    </records>
'''

How to do it with Groovy? 如何用Groovy做到这一点? comments are welcome. 欢迎评论。

I went down a similar route to danb, but ran into problems when actually printing out the resulting XML. 我沿着类似的路线前往danb,但在实际打印出生成的XML时遇到了问题。 Then I realized that the NodeList that was returned by asking the root for all of it's "car" children isn't the same list as you get by just asking for the root's children. 然后我意识到通过向root询问其所有“car”子项而返回的NodeList与通过询问root的子项获得的列表不同。 Even though they happen to be the same lists in this case, they wouldn't always be if there were non "car" children under the root. 尽管在这种情况下它们碰巧是相同的列表,但如果在根目录下有非“汽车”子项,它们并不总是如此。 Because of this, reording the list of cars that come back from the query doesn't affect the initial list. 因此,重新记录从查询返回的汽车列表不会影响初始列表。

Here's a solution that appends and reorders: 这是一个附加和重新排序的解决方案:

def CAR_RECORDS = '''
   <records>
     <car name='HSV Maloo' make='Holden' year='2006'/>
     <car name='P50' make='Peel' year='1962'/>
     <car name='Royale' make='Bugatti' year='1931'/>
   </records>
 '''

def carRecords = new XmlParser().parseText(CAR_RECORDS)

def cars = carRecords.children()
def royale = cars.find { it.@name == 'Royale' } 
cars.remove(royale)
cars.add(0, royale)
def newCar = new Node(carRecords, 'car', [name:'My New Car', make:'Peel', year:'1962'])

assert ["Royale", "HSV Maloo", "P50", "My New Car"] == carRecords.car*.@name

new XmlNodePrinter().print(carRecords)

The assertion with the propertly ordered cars passes, and the XmlNodePrinter outputs: 带有属性订购汽车的断言通过,XmlNodePrinter输出:

<records>
  <car year="1931" make="Bugatti" name="Royale"/>
  <car year="2006" make="Holden" name="HSV Maloo"/>
  <car year="1962" make="Peel" name="P50"/>
  <car name="My New Car" make="Peel" year="1962"/>
</records>

ted, maybe you did not notice that I wanted to '''insert a new car just after car"HSV Maloo"''', so I modify your code to : 特德,也许你没注意到我想在汽车“HSV Maloo”'''之后插入一辆新车,所以我将你的代码修改为:

def newCar = new Node(null, 'car', [name:'My New Car', make:'Peel', year:'1962'])
cars.add(2, newCar)

new XmlNodePrinter().print(carRecords)

now, it works with proper order! 现在,它适用于正确的订单! thanks to danb & ted. 感谢danb&ted。

<records>
  <car year="1931" make="Bugatti" name="Royale"/>
  <car year="2006" make="Holden" name="HSV Maloo"/>
  <car name="My New Car" make="Peel" year="1962"/>
  <car year="1962" make="Peel" name="P50"/>
</records>

<hand-wave> these are not the codz you seek </hand-wave> <手波> 这些不是你寻求的密码 </ hand-wave>

Node root = new XmlParser().parseText(CAR_RECORDS)
NodeList carNodes = root.car
Node royale = carNodes[2]
carNodes.remove(royale)
carNodes.add(0, royale)
carNodes.add(2, new Node(root, 'car', [name:'My New Card', make:'Peel', year:'1962']))

I don't know if there's a smarter way to create new nodes... but that works for me. 我不知道是否有更聪明的方法来创建新节点......但这对我有用。

EDIT: uhg... thanks guys... I got lazy and was printing carNodes when i tested this instead of the root... yikes. 编辑:呃...谢谢你们...我懒得打印carNodes,当我测试这个而不是根... yikes。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM