2

我有一个 xml 文件,它代表一个简单的“脚本”,其中特定元素代表不同的命令。

我想使用 groovy 来解析和“解释”xml 文件。我如何遍历 xml 文件的节点。

我正在使用 xmlSlurper 类来解析我的 xml 文件:

def records = new XmlSlurper().parse("./script.xml")

现在我需要从上到下遍历元素并运行一些常规代码......

只是一个示例文件:

<script>  
<do> echo :) </do>  
<for from="0" to="3">
     <do> echo hello </do>
</for>
</script>
4

2 回答 2

7

最好的办法是查看Groovy XmlSlurper 用户指南,其中有几个很好的示例。

例如,您可以遍历每个子节点(<script>标签将被排除):

def visit(node) {
    node.childNodes().each { child ->
        println child.name
        visit(child)
    }
}

def records = new XmlSlurper().parse("./script.xml")
visit(records)

输出将是

do
for
do

visit函数可以更新为闭包:

def visit(node, Closure c) {
    node.childNodes().each { child ->
        c(child)
        visit(child, c)
    }
}

def records = new XmlSlurper().parse("./script.xml")
visit(records) { node ->
    println node.name
}
于 2012-09-20T11:22:09.443 回答
1

引起了我的兴趣,所以我想出了这个:

class XmlRunner {
  def doFor( node ) {
    ((node.@from.text() as Integer)..(node.@to.text() as Integer)).each {
      run( node )
    }
  }

  def doDo( node ) {
    node.text().split().with {
      [it.head(), it.tail()]
    }.with { String cmd, rest ->
      "exec${cmd.capitalize()}"( rest )
    }
  }

  def execEcho( rest ) {
    println rest.join( ' ' )
  }

  def run( root ) {
    root.children().each {
      "do${it.name().capitalize()}"( it )
    }
  }

  static run( String xml ) {
    new XmlRunner().run( new XmlSlurper().parseText( xml ) )
  }

  static run( File xml ) {
    new XmlRunner().run( new XmlSlurper().parse( xml ) )
  }
}

XmlRunner.run( '''<script>  
                 |  <do> echo :) </do>  
                 |  <for from="0" to="3">
                 |    <do> echo hello </do>
                 |  </for>
                 |</script>'''.stripMargin() )

但是,必须提出以下问题:

  1. 为什么不只执行一个 Groovy 脚本?
  2. 如果它必须是 XML,为什么 echo 没有得到它自己的节点?
  3. for节点应该有一个变量吗?

我只需将其更改为 Groovy 脚本,例如:

println ':)'
4.times { println 'hello' }

并以通常的方式从 Groovy 运行它,而不是尝试定义您自己的 XML 语言(除非您有一个非常好的理由我错过了编写您自己的 XML 语言?)

于 2012-09-20T13:50:12.397 回答