2013-03-06 5 views
2

Я пытаюсь использовать Groovy разобрать следующий XML:Groovy скрипт не разбор XML правильно

<list> 
    <list> 
     <widget> 
      <fizz id="3" /> 
      <buzz>false</buzz> 
      <explanations/> 
     </widget> 
     <widget> 
      <fizz id="3" /> 
      <buzz>true</buzz> 
      <explanations> 
       <string>What is the meaning of life?</string> 
       <string>I like the color blue.</string> 
      </explanations> 
     </widget> 
     <widget> 
      <fizz id="45" /> 
      <buzz>true</buzz> 
      <explanations> 
       <string>I could really go for some pizza right now.</string> 
      </explanations> 
     </widget> 
    </list> 
</list> 

Если <widget/> элемента имеет true<buzz/> ребенка, то он начнет агрегирование всех explanations/string детей в мастер List<String> , Таким образом, учитывая XML примера выше, будет иметь следующее поведение:

  1. Первую list/list/widget/buzz является false, так что ничего
  2. Второго list/list/widget/buzz является true не делать, поэтому заниматься агрегации Струнного режимом:
    1. Второй list/list/widget/explanations имеет 2 <string/> детей; добавьте их обоих к главному списку (masterList)
  3. Третий list/list/widget/buzz является true, поэтому продолжают агрегирование своих детей натягивает в основной список
    1. Третий list/list/widget/explanations имеет 1 <string/> ребенка; добавить его в основной список (masterList)
  4. masterList теперь имеет 3 строки в нем: 2 из 2 виджета, и 1 из 3 виджета

До сих пор, вот моя лучшая попытка:

boolean buzzesExist = false; 
List<String> masterList = new ArrayList<String>(); 

use(DOMCategory) { 
    element.normalize(); 

    element.'widget'.each { widget -> 
     // If widget/buzz is true, then buzzes exist. 
     if(widget.'buzz'.text) { 
      buzzesExist = true; 
     } 

     // If buzzes exist, then aggregate all explanation strings into 
     // into "masterList". 
     if(buzzesExist) { 
      for(String exp : widget.'explanations') 
       masterList.add(exp); 
    } 
} 

Это работает, но приводит к тому, masterList содержать все виды Bizarro DOM вещей в нем (слишком большой для меня, чтобы вставить). Может ли какое-нибудь Гроуви-гуру найти место, где я буду вздрагивать? Заранее спасибо.

+0

Переменная buzzesExist никогда не возвращается к false, поэтому после первого виджета с шумом вы будете делать второй для – iberbeu

+0

Хороший улов, но все в порядке. Позже в скрипте я проверяю, есть ли 'buzzesExist', и я делаю с ним что-то еще. – IAmYourFaja

+0

Что вы точно получаете в masterList? – iberbeu

ответ

1

Почему бы не XmlParser?

UPDATE:

list = new XmlParser().parseText xml 

widgetWithExplanations = list.breadthFirst() 
    .findAll { it.buzz.text() == "true" } 

masterList = widgetWithExplanations 
    .collect { it.explanations.string*.text() } 
    .flatten() 

assert masterList == [ 
    "What is the meaning of life?", 
    "I like the color blue.", 
    "I could really go for some pizza right now."] 


emptyExplanations = widgetWithExplanations 
    .count { !it.explanations.string } 

assert emptyExplanations == 0 

В противном случае ваш domcategory, вероятно, отсутствует exp.text() внутри для цикла.

+0

Спасибо @Will P (+1) - два последующих действия: как бы я (1) проверить, имеет ли 'объяснений' размер 0 или нет, и сохранить это в bool, и (2) как я могу сохранить объяснения в 'Список ' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Еще раз спасибо! – IAmYourFaja

+0

Обновлено. Теперь он подсчитывает, сколько объяснений пусто (переменная 'emptyExplanations') и сохраняет строки в переменной' masterList' – Will

+0

Еще раз спасибо @Will P !!! Последнее продолжение, я обещаю! В каком пакете хранится 'XmlParser'? Я не могу найти его в Java 6 или Java 7. Какие операторы импорта мне нужно использовать для импорта в сценарий и сделать его доступным? Еще раз спасибо! – IAmYourFaja

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