解析器和slurper之间的大小差异?

时间:2012-11-13 03:49:41

标签: groovy xml-parsing

我正在尝试使用groovy进行xml处理,但仍然难以理解其行为。有人可以向我解释为什么下面的程序会吐出1和0吗?我在两种情况下都期待0,因为'onenode'元素没有孩子......我在这里缺少什么?

def text = """
 <characters>
   <props>
      <prop>dd</prop>
   </props>
   <character id="1" name="Wallace">
       <likes>cheese</likes>
   </character>
   <character id="2" name="Gromit">
       <likes>sleep</likes>
   </character>
   <onenode>help</onenode>
</characters>
"""

def xmlp = new XmlParser().parseText(text)
println xmlp.onenode[0].children().size() // prints out 1

def xmls = new XmlSlurper().parseText(text)
println xmls.onenode[0].children().size() // prints out 0

1 个答案:

答案 0 :(得分:1)

区别在于构建解析树的方式(在使用的类中以及方法的工作方式)。

如果我们写一个闭包来询问树:

def dumpTypeTree = { node, prefix = '' ->
  def name  = node.respondsTo( 'name' ) ? "${node.name()} -- " : ''
  def clazz = node.getClass().name
  def txt   = node.respondsTo('text') ? node.text() : node
  println "${prefix}${name}${clazz} '${txt}'"
  if( node.respondsTo( 'children' ) ) {
    node.children().each { child ->
      owner.call( child, "$prefix  " )
    }
  }
}

当我们使用XmlParser构造的树调用此方法时:

dumpTypeTree( new XmlParser().parseText(text) )

我们得到:

characters -- groovy.util.Node ''
  props -- groovy.util.Node ''
    prop -- groovy.util.Node 'dd'
      java.lang.String 'dd'
  character -- groovy.util.Node ''
    likes -- groovy.util.Node 'cheese'
      java.lang.String 'cheese'
  character -- groovy.util.Node ''
    likes -- groovy.util.Node 'sleep'
      java.lang.String 'sleep'
  onenode -- groovy.util.Node 'help'
    java.lang.String 'help'

如您所见,onenode节点包含String,它是该节点的文本内容。 text()调用会返回我们期望的内容。

但是,使用XmlSlurper调用它:

dumpTypeTree( new XmlSlurper().parseText(text) )

给我们:

characters -- groovy.util.slurpersupport.NodeChild 'ddcheesesleephelp'
  props -- groovy.util.slurpersupport.NodeChild 'dd'
    prop -- groovy.util.slurpersupport.NodeChild 'dd'
  character -- groovy.util.slurpersupport.NodeChild 'cheese'
    likes -- groovy.util.slurpersupport.NodeChild 'cheese'
  character -- groovy.util.slurpersupport.NodeChild 'sleep'
    likes -- groovy.util.slurpersupport.NodeChild 'sleep'
  onenode -- groovy.util.slurpersupport.NodeChild 'help'

正如您所看到的,没有String个子节点,只在叶子节点上调用text()会有任何意义,因为在叶子之外,我们将所有文本连接在一起。

无论如何,希望这能解释孩子数量的差异