Groovy
中, 自帶了
xml
處理的相關類, 操作起來也是相當nice的.
本文操作執行個體在
Android
開發環境中進行.
測試的xml檔案:
def targetFile = new File("${buildFile.parent}/src/main/res/values/strings.xml")
def testFile = new File("${buildFile.parent}/src/main/res/values/strings_test.xml")
def afterFile = new File("${buildFile.parent}/src/main/res/values/strings_after.xml")
文章目錄
- 打開xml檔案
- 擷取值
- 修改值
- 删除值
- 添加值
- 儲存xml到檔案
- 建立xml格式資料
- 附贈XmlParser多級操作
- 聯系作者
groovy.util.XmlSlurper
groovy.util.XmlParser
XmlSlurper
這個類, 在讀取
xml
檔案方面, 相當友善.
可以直接使用
xml
檔案中的
tag名
,直接讀取對應的值
XmlParser
這個類, 在修改
xml
檔案方面, 相當友善.
各種操作的
api
都有方法.
打開xml檔案
/**
*
* 擷取一個 GPathResult 對象
* @see groovy.util.slurpersupport.GPathResult
* */
static def openXml(xml) {
def xmlSlurper = new XmlSlurper()
def result = xmlSlurper.parse(xml)
return result
}
static def openXmlText(xmlText) {
def xmlSlurper = new XmlSlurper()
def result = xmlSlurper.parseText(xmlText)
return result
}
擷取值
static def getValue(pathResult, key) {
return getNodeChildren(pathResult, key)[0].text()
}
/**
* 擷取屬性名為 name 值為 key 的 Node
* */
static def getNodeChildren(pathResult, key) {
pathResult?.depthFirst()?.findAll { node ->
if (node["@name"] == key) {
return node
}
}
}
修改值
/**
* @return 傳回修改之前的值
* */
static def setValue(pathResult, key, value) {
def nodeChildren = getNodeChildren(pathResult, key)
def oldValue = nodeChildren[0].text()
nodeChildren[0].replaceBody(value)
return oldValue
}
删除值
/**
* XmlSlurper 實在是沒有找到 删除 node 的方法.
* 是以, 這裡使用 XmlParser 删除了 node,
* 再重新傳回 GPathResult 對象
*
* @see groovy.util.XmlSlurper
* @see groovy.util.XmlParser
* */
static def deleteKey(pathResult, key) {
def xmlText = groovy.xml.XmlUtil.serialize(pathResult)
def xmlParser = new groovy.util.XmlParser()
def rootNode = xmlParser.parseText(xmlText)
def deleteNode = null
rootNode.depthFirst().each {
//println "tag:${it.name()} name:${it.attributes()["name"]} value:${it.value()} childs:${it.children.size()}"
if (it.attributes()["name"] == key) {
deleteNode = it
}
}
deleteNode?.parent()?.remove(deleteNode)
def afterXmlText = groovy.xml.XmlUtil.serialize(rootNode)
return openXmlText(afterXmlText)
}
添加值
/**
* @see #deleteKey
*
* */
static def addKey(pathResult, key, value) {
def xmlText = groovy.xml.XmlUtil.serialize(pathResult)
def xmlParser = new groovy.util.XmlParser()
def rootNode = xmlParser.parseText(xmlText)
def targetNode = null
rootNode.depthFirst().each {
//println "tag:${it.name()} name:${it.attributes()["name"]} value:${it.value()} childs:${it.children.size()}"
if (it.name() == "resources") {
targetNode = it
}
}
targetNode?.append(new groovy.util.Node(null, "string", ["name": key], value))
def afterXmlText = groovy.xml.XmlUtil.serialize(rootNode)
return openXmlText(afterXmlText)
}
儲存xml到檔案
/**
* 儲存到指定檔案
* */
static def save(targetFile, xml) {
def text = null
if (xml instanceof groovy.util.slurpersupport.GPathResult) {
text = groovy.xml.XmlUtil.serialize(xml)
} else {
text = xml.toString()
}
def tempFile = null
if (targetFile instanceof File) {
tempFile = targetFile
} else {
tempFile = new File(targetFile)
}
tempFile.withWriter("UTF8") { writer ->
writer.write(text)
}
}
建立xml格式資料
def stringWrite = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(stringWrite)
builder.resources() {
'string'(name: "app_name", name2: "app_name_2", "test_value1")
'string'(name: 'app_name2', 'test_value2')
}
def xmlText = stringWrite.toString()
附贈XmlParser多級操作
def targetFile = new File("${buildFile.parent}/src/main/res/values/styles.xml")
gradle.projectsEvaluated {
def rootNode = openXml(targetFile)
println "......xml......"
println rootNode.name()
if ("resources" == rootNode.name()) {
//確定根節點是 resources
//去重後的 nodes
def resultNodes = [:]
//需要删除的 nodes
def deleteNodes = []
rootNode.children().each {
//name 屬性的值
def name = it.attributes()["name"]
def node = resultNodes[name]
if (node != null) {
println "找到重複屬性, name為 ${name}"
deleteNodes += node
} else {
println "新增節點, name為 ${name}"
resultNodes[name] = it
}
//println it.name() + it.attributes()["name"]
}
println 'xml...原内容'
logXmlText(rootNode)
def childs = rootNode.children()
for (int i = childs.size() - 1; i >= 0; i--) {
rootNode.remove(childs[i])
}
println 'xml...去重後'
resultNodes.each { _, node ->
rootNode.append(node)
}
logXmlText(rootNode)
save(targetFile, rootNode)
}
}
static def openXml(xml) {
def xmlParser = new groovy.util.XmlParser()
def result = xmlParser.parse(xml)
return result
}
static def openXmlText(xmlText) {
def xmlParser = new groovy.util.XmlParser()
def result = xmlParser.parseText(xmlText)
return result
}
static def logXmlText(node) {
def xmlText = groovy.xml.XmlUtil.serialize(node)
println xmlText
}
/**
* 儲存到指定檔案
* */
static def save(targetFile, xml) {
def text = null
if (xml instanceof groovy.util.slurpersupport.GPathResult ||
xml instanceof groovy.util.Node) {
text = groovy.xml.XmlUtil.serialize(xml)
} else {
text = xml.toString()
}
def tempFile = null
if (targetFile instanceof File) {
tempFile = targetFile
} else {
tempFile = new File(targetFile)
}
//println "儲存:$targetFile"
//println "儲存:$text"
tempFile.withWriter("UTF8") { writer ->
writer.write(text)
}
}
DSL源碼參考 推薦閱讀
群内有
各(pian)種(ni)各(jin)樣(qun)
的大佬,等你來撩.
聯系作者
點此快速加群
請使用QQ掃碼加群, 小夥伴們都在等着你哦!

關注我的公衆号, 每天都能一起玩耍哦!