使用tagsoup和Groovy的XmlSlurper的奇怪行为

时间:2011-01-27 02:44:43

标签: xml parsing groovy tag-soup

假设我想解析一个xml字符串中的电话号码,如下所示:

str = """ <root> 
            <address>123 New York, NY 10019
                <div class="phone"> (212) 212-0001</div> 
            </address> 
        </root> 
    """
parser = new XmlSlurper(new org.ccil.cowan.tagsoup.Parser()).parseText (str)
println parser.address.div.text()

它不会打印电话号码。

如果我将“div”元素改为“foo”,就像这样

str = """ <root> 
            <address>123 New York, NY 10019
                <foo class="phone"> (212) 212-0001</foo> 
            </address> 
        </root> 
    """
parser = new XmlSlurper(new org.ccil.cowan.tagsoup.Parser()).parseText (str)
println parser.address.foo.text()

然后它能够​​解析并打印电话号码。

到底发生了什么事?

顺便说一句,我正在使用groovy 1.7.5和tagsoup 1.2

3 个答案:

答案 0 :(得分:1)

只需将代码更改为

即可
println parser.address.'div'.text()

这是Groovy和许多其他动态语言的诅咒 - “div”是保留的方法名,因此你没有得到节点而是试图划分“地址”节点:)

答案 1 :(得分:0)

我似乎记得,tagoup规范化HTML标签 - 即它标注它们。所以你想要的GPath表达式可能是

println parser.ADDRESS.DIV.text()

我觉得能够打印出解析结果很方便 - 然后你就会明白为什么你的GPath不能正常工作。用这个..

println groovy.xml.XmlUtil.serialize(parser)

答案 2 :(得分:0)

我知道这个问题很老了。但是我最近遇到了这就是我用过的东西:

parser.'**'.findAll { it.name() == 'div' && it.@class.text() == 'phone' }.each { div ->
    println div.text()
}
  1. 使用depthFirst查找所有标记
  2. 按名称 div 进行过滤电话;
  3. 打印值(212)212-0001
  4. Groovy版本是2.4