如何在没有 GPath/node 名称的情况下提取 CDATA
How to extract CDATA without the GPath/node name
我试图在不使用 GPath(或)节点名称的情况下从 XML 中提取 CDATA 内容。简而言之,我想从 XML 中查找并检索包含 CDATA 部分的 innerText。
我的 XML 看起来像:
def xml = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<Test1>This node contains some innerText. Ignore This.</Test1>
<Test2><![CDATA[this is the CDATA section i want to retrieve]]></Test2>
</root>'''
从上面XML,我想单独获取CDATA内容而不使用其节点名称的引用'Test2'。因为节点名称在我的场景中并不总是相同的。
另请注意,XML 可以在其他几个节点 (Test1) 中包含 innerText。我不想找回那个。我只需要整个 XML 中的 CDATA 内容。
我想要像下面这样的东西(虽然下面的代码不正确)
def parsedXML = new xmlSlurper().parseText(xml)
def cdataContent = parsedXML.depthFirst().findAll { it.text().startsWith('<![CDATA')}
我的输出应该是:
this is the CDATA section i want to retrieve
正如@daggett 所说,您不能使用 Groovy slurper 或解析器来执行此操作,但是下拉并使用 java 类 来获取也不错它。
请注意,您必须设置 属性 才能使 CDATA 可见,因为默认情况下它仅被视为字符。
代码如下:
import javax.xml.stream.*
def xml = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<Test1>This node contains some innerText. Ignore This.</Test1>
<Test2><![CDATA[this is the CDATA section i want to retrieve]]></Test2>
</root>'''
def factory = XMLInputFactory.newInstance()
factory.setProperty('http://java.sun.com/xml/stream/properties/report-cdata-event', true)
def reader = factory.createXMLStreamReader(new StringReader(xml))
while (reader.hasNext()) {
if (reader.eventType in [XMLStreamConstants.CDATA]) {
println reader.text
}
reader.next()
}
这将打印 this is the CDATA section i want to retrieve
考虑到您的 xml split 中只有一个 CDATA 可以提供帮助
def xml = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<Test1>This node contains some innerText. Ignore This.</Test1>
<Test2><![CDATA[this is the CDATA section i want to retrieve]]></Test2>
</root>'''
log.info xml.split("<!\[CDATA\[")[1].split("]]")[0]
所以在上面的逻辑中,我们在 CDATA 开始时拆分字符串并选择
之后剩下的部分
xml.split("<!\[CDATA\[")[1]
一旦我们得到那部分,我们再次进行拆分,然后通过使用
得到该模式之前的部分
.split("]]")[0]
这是它有效的证明
我试图在不使用 GPath(或)节点名称的情况下从 XML 中提取 CDATA 内容。简而言之,我想从 XML 中查找并检索包含 CDATA 部分的 innerText。
我的 XML 看起来像:
def xml = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<Test1>This node contains some innerText. Ignore This.</Test1>
<Test2><![CDATA[this is the CDATA section i want to retrieve]]></Test2>
</root>'''
从上面XML,我想单独获取CDATA内容而不使用其节点名称的引用'Test2'。因为节点名称在我的场景中并不总是相同的。
另请注意,XML 可以在其他几个节点 (Test1) 中包含 innerText。我不想找回那个。我只需要整个 XML 中的 CDATA 内容。
我想要像下面这样的东西(虽然下面的代码不正确)
def parsedXML = new xmlSlurper().parseText(xml)
def cdataContent = parsedXML.depthFirst().findAll { it.text().startsWith('<![CDATA')}
我的输出应该是:
this is the CDATA section i want to retrieve
正如@daggett 所说,您不能使用 Groovy slurper 或解析器来执行此操作,但是下拉并使用 java 类 来获取也不错它。
请注意,您必须设置 属性 才能使 CDATA 可见,因为默认情况下它仅被视为字符。
代码如下:
import javax.xml.stream.*
def xml = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<Test1>This node contains some innerText. Ignore This.</Test1>
<Test2><![CDATA[this is the CDATA section i want to retrieve]]></Test2>
</root>'''
def factory = XMLInputFactory.newInstance()
factory.setProperty('http://java.sun.com/xml/stream/properties/report-cdata-event', true)
def reader = factory.createXMLStreamReader(new StringReader(xml))
while (reader.hasNext()) {
if (reader.eventType in [XMLStreamConstants.CDATA]) {
println reader.text
}
reader.next()
}
这将打印 this is the CDATA section i want to retrieve
考虑到您的 xml split 中只有一个 CDATA 可以提供帮助
def xml = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<Test1>This node contains some innerText. Ignore This.</Test1>
<Test2><![CDATA[this is the CDATA section i want to retrieve]]></Test2>
</root>'''
log.info xml.split("<!\[CDATA\[")[1].split("]]")[0]
所以在上面的逻辑中,我们在 CDATA 开始时拆分字符串并选择
之后剩下的部分xml.split("<!\[CDATA\[")[1]
一旦我们得到那部分,我们再次进行拆分,然后通过使用
得到该模式之前的部分.split("]]")[0]
这是它有效的证明