使用新的 'file' 节点在 Gradle/Groovy 中操作 XML
Manipulating XML in Gradle/Groovy with new 'file' node
我正在尝试操纵 wildfly 10.1。 standalone.xml
通过 gradle buildscript 修改记录器设置。我以前做过这个,并且使用记录器条目,这按预期工作。但是,现在我需要添加一个新的 periodic-rotating-file-handler
,这本身不是问题,但在尝试告诉实际登录到哪个文件时它确实起作用了。
现有代码:
def configFile = {wildflyDir}/standalone/configuration/standalone.xml"
def xml = new XmlSlurper(false,false).parse(configFile)
def logging = xml.profile.subsystem.find{ it['@xmlns'] == "urn:jboss:domain:logging:3.0' }
logging.appendNode {
logger(category:"loggingCategory") {
level(name:"LEVEL")
}
}
正如预期的那样,这是非常实用的。现在我需要添加这样的片段:
<periodic-rotating-file-handler>
<formatter>
<named-formatter name="PATTERN" />
</formatter>
<file path="file.log" relative-to="jboss.logging.dir" />
<suffix value=".yyyy-MM-dd" />
<append value="true" />
</periodic-rotating-file-handler>
file
定义中存在问题,因为 build.gradle
文件中的定义如下所示:
file(path:"file.log" "relative-to":"jboss.logging.dir")
这被 gradle 解释为 new File(arg1, arg2)
,所以基本上它试图将具有给定参数的文件对象添加到 XML.
这是有效的,但绝对不是我想要的,因为我只需要相应的 XML 节点。我尝试了多种逃脱方式:
- 使用单引号、双引号、三引号转义
file
,使其成为斜线和美元斜线字符串 -> 尝试创建文件对象
- 使用相同的选项转义整行 -> XML
中不存在该行
- 尝试添加不带括号的节点 -> 尝试创建文件对象
- 尝试添加为额外的闭包 -> 尝试创建文件对象
- 尝试将节点提取为文本,使用 XMLSlurper 进行解析并将其添加到 XML -> XML
中不存在的片段
还有一些我尝试过的东西,但由于沮丧我想不起来了。
我最后的尝试是尝试向 XML 添加一个空的 file
节点,但是当使用 file()
时 gradle 不知道哪个文件构造器使用,当我使用 file
时出现错误:Namespace prefix: file is not bound to a URI
如果有人知道如何正确转义 file
或者有其他方法可以将所述 file
-node 添加到 XML,请告诉我。
谢谢。
(1) 在委托上调用生成器函数:
//just declare `file` to emulate problem in usual groovy console
def file={String a, String b-> println "file: a=$a, b=$b"}
def xml = new XmlSlurper(false,false).parseText('''
<root>
<profile>
<subsystem xmlns="urn:jboss:domain:logging:3.0"/>
</profile>
</root>''')
def logging = xml.profile.subsystem.find{ it['@xmlns'] == "urn:jboss:domain:logging:3.0" }
logging.plus{
logger(category:"loggingCategory") {
level(name:"LEVEL")
}
//be specific that you want to call file function on delegate and not on owner (by default)
delegate.'file'(path:"file.log", "relative-to":"jboss.logging.dir")
//or this also works:
"${'file'}"(path:"file.log", "relative-to":"jboss.logging.dir")
}
println groovy.xml.XmlUtil.serialize(xml)
(2) 使用 XmlParser 的解决方法:
使用current
作为当前父节点的访问者
def xml = new XmlParser(false,false).parseText('''
<root>
<profile>
<subsystem xmlns="urn:jboss:domain:logging:3.0"/>
</profile>
</root>''')
def logging = xml.profile.subsystem.find{ it['@xmlns'] == "urn:jboss:domain:logging:3.0" }
logging.plus{
logger(category:"loggingCategory") {
level(name:"LEVEL")
}
current.appendNode("file", [path:"file.log", "relative-to":"jboss.logging.dir"])
}
println groovy.xml.XmlUtil.serialize(xml)
我正在尝试操纵 wildfly 10.1。 standalone.xml
通过 gradle buildscript 修改记录器设置。我以前做过这个,并且使用记录器条目,这按预期工作。但是,现在我需要添加一个新的 periodic-rotating-file-handler
,这本身不是问题,但在尝试告诉实际登录到哪个文件时它确实起作用了。
现有代码:
def configFile = {wildflyDir}/standalone/configuration/standalone.xml"
def xml = new XmlSlurper(false,false).parse(configFile)
def logging = xml.profile.subsystem.find{ it['@xmlns'] == "urn:jboss:domain:logging:3.0' }
logging.appendNode {
logger(category:"loggingCategory") {
level(name:"LEVEL")
}
}
正如预期的那样,这是非常实用的。现在我需要添加这样的片段:
<periodic-rotating-file-handler>
<formatter>
<named-formatter name="PATTERN" />
</formatter>
<file path="file.log" relative-to="jboss.logging.dir" />
<suffix value=".yyyy-MM-dd" />
<append value="true" />
</periodic-rotating-file-handler>
file
定义中存在问题,因为 build.gradle
文件中的定义如下所示:
file(path:"file.log" "relative-to":"jboss.logging.dir")
这被 gradle 解释为 new File(arg1, arg2)
,所以基本上它试图将具有给定参数的文件对象添加到 XML.
这是有效的,但绝对不是我想要的,因为我只需要相应的 XML 节点。我尝试了多种逃脱方式:
- 使用单引号、双引号、三引号转义
file
,使其成为斜线和美元斜线字符串 -> 尝试创建文件对象 - 使用相同的选项转义整行 -> XML 中不存在该行
- 尝试添加不带括号的节点 -> 尝试创建文件对象
- 尝试添加为额外的闭包 -> 尝试创建文件对象
- 尝试将节点提取为文本,使用 XMLSlurper 进行解析并将其添加到 XML -> XML 中不存在的片段
还有一些我尝试过的东西,但由于沮丧我想不起来了。
我最后的尝试是尝试向 XML 添加一个空的 file
节点,但是当使用 file()
时 gradle 不知道哪个文件构造器使用,当我使用 file
时出现错误:Namespace prefix: file is not bound to a URI
如果有人知道如何正确转义 file
或者有其他方法可以将所述 file
-node 添加到 XML,请告诉我。
谢谢。
(1) 在委托上调用生成器函数:
//just declare `file` to emulate problem in usual groovy console
def file={String a, String b-> println "file: a=$a, b=$b"}
def xml = new XmlSlurper(false,false).parseText('''
<root>
<profile>
<subsystem xmlns="urn:jboss:domain:logging:3.0"/>
</profile>
</root>''')
def logging = xml.profile.subsystem.find{ it['@xmlns'] == "urn:jboss:domain:logging:3.0" }
logging.plus{
logger(category:"loggingCategory") {
level(name:"LEVEL")
}
//be specific that you want to call file function on delegate and not on owner (by default)
delegate.'file'(path:"file.log", "relative-to":"jboss.logging.dir")
//or this also works:
"${'file'}"(path:"file.log", "relative-to":"jboss.logging.dir")
}
println groovy.xml.XmlUtil.serialize(xml)
(2) 使用 XmlParser 的解决方法:
使用current
作为当前父节点的访问者
def xml = new XmlParser(false,false).parseText('''
<root>
<profile>
<subsystem xmlns="urn:jboss:domain:logging:3.0"/>
</profile>
</root>''')
def logging = xml.profile.subsystem.find{ it['@xmlns'] == "urn:jboss:domain:logging:3.0" }
logging.plus{
logger(category:"loggingCategory") {
level(name:"LEVEL")
}
current.appendNode("file", [path:"file.log", "relative-to":"jboss.logging.dir"])
}
println groovy.xml.XmlUtil.serialize(xml)