Как извлечь CDATA без имени GPath / узла - PullRequest
0 голосов
/ 17 сентября 2018

Я пытаюсь извлечь содержимое CDATA из XML без использования имени узла GPath (или).Короче говоря, я хочу найти и получить innerText, содержащий раздел CDATA, из XML.

Мой 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 может содержать innerText в нескольких других узлах (Test1).Я не хочу, чтобы восстановить это.Мне просто нужен контент CDATA из всего XML.

Я хочу что-то вроде ниже (хотя приведенный ниже код неверен)

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 голосов
/ 20 сентября 2018

Учитывая, что у вас есть только один CDATA в вашем xml split , здесь может помочь

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

0 голосов
/ 18 сентября 2018

Как говорит @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

...