2015-07-22 2 views
1

Мне нужно прочитать XML и сохранить значения атрибута в переменной. Поскольку я новичок в Groovy, мне становится сложно. Пока это то, что я сделал.Groovy: разбор XML и сохранение значений атрибутов переменным

PS: Это то, что я делаю внутри метода.

XmlParser parser = new XmlParser() 
//def xmldata1 = parser.parse (new FileInputStream("c:\\temp\\create.xml")) 

def xml = """<record_change> 
<record_id>04707317-28e3-40cb-a227-15d2c91e08c2</record_id> 
<incident number="201507-001" status="open"/> 
</record_change>""" 

def xmldata1 = parser.parseText(xml) 
def n_id = xmldata1.record_id.????? 
def n_number = ????? //expecting incident number 
def m_status = ????? // expecting incident status 

Помогло ли мне кто-нибудь?

ответ

3

Короткий ответ заключается в следующем:

def n_id  = xmldata1.record_id[0].text() 
def n_number = xmldata1.incident[0][email protected] 
def m_status = xmldata1.incident[0][email protected] 

Примечания это немного отличается от ответа Джаян в связи с индексацией нодлиста к отдельному узлу , В вашем случае это не проблема для n_id, но вам понадобятся индексы для n_number и m_status, иначе они будут списками. Кроме того, если вы получаете данные, где в NodeList имеется более одного узла, у вас появятся проблемы. См. Пример text() позже в моем ответе.

Для этого типа расследования ваш лучший выбор - groovysh, а затем непосредственно допросить объекты.

Вот сессии, в которой это в действии:

groovy:000> p = new XmlParser() 
===> [email protected] 

groovy:000> xml = '<record_change><record_id>04707317-28e3-40cb-a227-15d2c91e08c2</record_id><incident number="201507-001" status="open"/></record_change>' 
===> <record_change><record_id>04707317-28e3-40cb-a227-15d2c91e08c2</record_id><incident number="201507-001" status="open"/></record_change> 

groovy:000> d = p.parseText(xml) 
===> record_change[attributes={}; value=[record_id[attributes={}; value=[04707317-28e3-40cb-a227-15d2c91e08c2]], incident[attributes={number=201507-001, status=open}; value=[]]]] 

Теперь мы имеем разобранный XML, и это в локальной переменной d. Вы уже можете видеть из toString() некоторые части, в которые она разбила его.

Возвращенный d является groovy.util.Node:

groovy:000> d.getClass() 
===> class groovy.util.Node 

d.record_id является groovy.util.NodeList:

groovy:000> d.record_id.getClass() 
===> class groovy.util.NodeList 

нодлист имеет text() метод на нем, который «возвращает текстовое представление текущего узла и все его дочерние узлы ». Теперь должны быть звонкие колокола. В последней части говорится «... и все его дочерние узлы». Там также text() метод на узле, так что если вы хотите быть уверены, чтобы не получить дополнительные ребенок, то индекс Нодлист:

groovy:000> d.record_id[0].text() 
===> 04707317-28e3-40cb-a227-15d2c91e08c2 

Если вы что-то вроде:

<record_change> 
    <record_id>1111</record_id> 
    <record_id>2222</record_id> 
</record_change> 

Затем вызывающего текста () на just record_id дал бы:

groovy:000> d.record_id.text() 
===> 11112222 

который, вероятно, не тот, который вы хотите. Будьте очень осторожны, если вы работаете над узлом или NodeList. Если вы знаете, что у вас есть только один узел в списке, то с вами все будет в порядке.

Для incident, вы найдете это и есть NodeList, но, очевидно, не имеет никакого текста часть, только атрибуты, как мы можем видеть из ToString() из нее:

groovy:000> d.incident 
===> [incident[attributes={number=201507-001, status=open}; value=[]]] 

Метод text() возвращает часть в value=[]. Но здесь есть атрибуты, доступные с помощью синтаксиса @attributeName. Во-первых, мы можем также использовать функцию attributes() для опроса их имен и значений (она возвращает обычную карту). Это функция Node, а не NodeList, поэтому мы должны индексировать NodeList с d.incident[0], чтобы получить узел из NodeList. Таким образом, мы имеем:

groovy:000> d.incident[0].attributes() 
===> [number:201507-001, status:open] 

groovy:000> d.incident[0].attributes().keySet() 
===> [number, status] 

Непосредственно, вы можете получить атрибуты, как это:

groovy:000> [email protected] 
===> [201507-001] 

Ах! мы вызвали @number в NodeList, поэтому он возвращает список значений (один в вашем случае, но если у вас более сложные данные, это будет несколько элементов). Если вы хотите, индивидуальное значение по своей собственной, индекс соответствующий элемент из NodeList как ранее сделано:

groovy:000> d.incident[0][email protected] 
===> 201507-001 

Так что будьте осторожны с индексацией, чтобы получить отдельный элемент узла.

Наконец, если вы ссылаетесь на элементы с дефисами в них, вы можете использовать кавычки вокруг него, чтобы получить значение, например. d.'some-element'[0].text().

+0

Это может быть справочный ответ. Ничего больше, чтобы добавить к нему. – Jayan

+1

спасибо @Jayan, это на самом деле, как я узнал, как использовать XML-анализ groovy's слишком много лун назад. –

2
  • Использование «@attributename» для получения значения атрибутов
  • имя
  • Используйте «элемент», чтобы добраться до элемента.

Вот ваш пример:

XmlParser parser = new XmlParser() 
//def xmldata1 = parser.parse (new FileInputStream("c:\\temp\\create.xml")) 

def xml = """<record_change> 
<record_id>04707317-28e3-40cb-a227-15d2c91e08c2</record_id> 
<incident number="201507-001" status="open"/> 
</record_change>""" 

def xmldata1 = parser.parseText(xml) ; 
def n_id = xmldata1.record_id.text() 
def n_number = xmldata1.'incident'[email protected] 
def m_status = [email protected] 

assert n_id == '04707317-28e3-40cb-a227-15d2c91e08c2' 


println(n_number) 
println(m_status) 
+1

Возможно, стоит отметить, что выполнение '@ attribute' в NodeList возвращает список значений атрибутов. Для проблемы OP я хотел бы использовать 'xmldata1.incident [0]. @ Number' для доступа к первому элементу и получить его атрибут напрямую, иначе вы эффективно выполняете операцию распространения по всем узлам и возвращаете их как список, который может быть желательным, но (я подозреваю) не в этом случае. –

Смежные вопросы