不求甚解

此博客为个人学习之用,如与其他作品雷同,纯属巧合。

导航

Q:Groovy 中 XmlSlurper 和 XmlParser 的详细使用教程

Posted on 2026-01-27 16:41  三年三班王小朋  阅读(0)  评论(0)    收藏  举报

以下是对 Groovy 中 XmlSlurperXmlParser 的详细使用教程,涵盖基本概念、核心区别、典型用法及注意事项,适用于实际开发场景。


一、概述

Groovy 提供了两种内置的 XML 处理工具:

  • XmlSlurper:用于快速读取和查询 XML 内容,适用于只读操作。
  • XmlParser:用于构建可修改的 XML 对象树,适用于需要修改结构或生成新 XML 的场景。

两者都基于 Java 的 SAX 或 DOM 解析器,但抽象层次和使用方式不同。


二、XmlSlurper —— 只读查询

1. 基本用法

def xmlText = '''
<bookstore>
  <book id="101">
    <title>Groovy in Action</title>
    <author>Dierk König</author>
    <price>49.99</price>
  </book>
  <book id="102">
    <title>Programming Groovy</title>
    <author>Venkat Subramaniam</author>
    <price>39.99</price>
  </book>
</bookstore>
'''

def xml = new XmlSlurper().parseText(xmlText)

2. 访问元素和属性

  • 获取文本内容:

    println xml.book[0].title.text()  // "Groovy in Action"
    
  • 获取属性:

    println xml.book[0].@id           // "101"
    
  • 遍历多个节点:

    xml.book.each { book ->
        println "${book.@id}: ${book.title.text()}"
    }
    
  • 条件查询:

    def expensiveBooks = xml.book.findAll { it.price.text().toDouble() > 40 }
    expensiveBooks.each { println it.title.text() }
    

3. 特点

  • 返回类型为 GPathResult,支持链式调用。
  • 对缺失节点宽容:访问不存在的标签不会抛异常,返回空结果。
  • 不可修改原始 XML:所有操作仅用于读取。
  • 适合解析配置文件、API 响应等只读场景。

4. 局限性

  • 无法修改节点值、属性或结构。
  • 不能直接输出修改后的 XML(因为没有“修改”能力)。

三、XmlParser —— 可修改的 XML 树

1. 基本用法

def xml = new XmlParser().parseText(xmlText)

2. 访问节点

注意:xml.book 返回的是 NodeList,即使只有一个节点。

def firstBook = xml.book[0]        // 获取第一个 <book> 节点(Node 类型)
def titleNode = firstBook.title[0] // 获取 <title> 节点
println titleNode.text()           // "Groovy in Action"

3. 修改节点内容

  • 修改文本值:

    titleNode.setValue("Advanced Groovy")
    
  • 修改属性:

    firstBook.@id = "201"
    

4. 替换或删除节点

  • 替换节点(重命名或改变结构):

    titleNode.replaceNode {
        bookTitle("Advanced Groovy")
    }
    
  • 删除节点:

    firstBook.remove(titleNode)
    
  • 添加子节点:

    firstBook.appendNode {
        isbn("978-1234567890")
    }
    

5. 输出修改后的 XML

使用 XmlNodePrinter 格式化输出:

def writer = new StringWriter()
def printer = new XmlNodePrinter(new PrintWriter(writer))
printer.preserveWhitespace = true
printer.print(xml)

String result = writer.toString()
println result

6. 特点

  • 返回由 Node 对象组成的树形结构。
  • 支持完整的增、删、改操作。
  • 严格模式:访问不存在的子节点可能抛出异常,需先判断 size() > 0
  • 适合报文转换、接口适配、XML 生成等场景。

四、关键区别总结

维度XmlSlurperXmlParser
主要用途 读取、查询 修改、生成
返回类型 GPathResult(只读) Node(可变)
修改能力 不支持 支持 setValue、replaceNode、appendNode 等
空节点处理 宽容,不报错 严格,需判空
内存占用 较低(惰性) 较高(完整树)
输出 XML 无法直接输出修改结果 可通过 XmlNodePrinter 输出

五、如何选择?

  • 使用 XmlSlurper 当

    • 你只需要从 XML 中提取数据;
    • 做条件判断或验证;
    • 处理大型 XML 且关注内存效率;
    • 不需要生成新的 XML 文档。
  • 使用 XmlParser 当

    • 你需要修改标签名、值、属性;
    • 要将一种 XML 格式转换为另一种(如医保接口改造);
    • 需要动态构建或输出 XML 字符串。

六、常见错误与建议

  1. 误用 Slurper 进行修改
    错误示例:

    def xml = new XmlSlurper().parseText(...)
    xml.tag = "new"  // 无效!不会改变原结构
    

    正确做法:改用 XmlParser

  2. Parser 中未处理 NodeList
    错误示例:

    xml.book.title.setValue("...")  // 报错:NodeList 没有 setValue
    

    正确做法:

    xml.book[0].title[0].setValue("...")
    
  3. 空值处理
    XmlParser 中,建议始终检查节点是否存在:

    if (xml.optionalTag?.size() > 0) {
        // 安全访问
    }
    

七、结论

  • XmlSlurper 是高效的 XML 查询工具,适合只读场景。
  • XmlParser 是功能完整的 XML 编辑器,适合需要修改或生成 XML 的业务。
  • 在接口报文转换、医疗/金融系统对接等场景中,XmlParser 是更常用的选择