如何在没有GPath /节点名称的情况下提取CDATA

时间:2018-09-17 16:31:15

标签: groovy cdata xmlslurper

我试图在不使用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

2 个答案:

答案 0 :(得分:1)

正如@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

答案 1 :(得分:1)

考虑到您的xml中只有一个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] 

这是行之有效的证明

enter image description here