2009-06-23 14 views
7

Chcę sprawdzić, czy dokument XML zawiera element "osoby" w dowolnym miejscu w środku. Mogę sprawdzić wszystkie elementy pierwszej generacji w bardzo prosty sposób:Powtórz wszystkie generacje węzłów XML w java DOM

NodeList nodeList = root.getChildNodes(); 
for(int i=0; i<nodeList.getLength(); i++){ 
    Node childNode = nodeList.item(i); 
    if (childNode.getNodeName() == "person") { 
    //do something with it 
    } 
} 

A i mogę dodać kolejne pętle, aby przejść do podelementy, ale muszę wiedzieć, ile zagnieżdżone pętle, aby umieścić w celu ustalenia, jak daleko w dokument do wiercenia. Mógłbym zagnieździć 10 pętli, a skończyłbym z elementem personalnym zagnieżdżonym 12 elementów głęboko w danym dokumencie. Muszę być w stanie wyciągnąć element nie ma znaczenia, jak głęboko jest to zagnieżdżone.

Czy można zbierać elementy z całego dokumentu? Podobnie jak zwracać wartości tekstowe wszystkich tagów jako tablicę lub iterować nad nią?

Coś podobnego do Pythona elementtree 'findAll' metoda być może:

for person in tree.findall('//person'): 
    personlist.append(person) 
+1

myślę, że trzeba http://en.wikipedia.org/wiki/Recursion_%28computer_science % 29. –

Odpowiedz

10

Jak mmyers stwierdza, można użyć rekurencji do tego problemu.

doSomethingWithAll(root.getChildNodes()); 

void doSomethingWithAll(NodeList nodeList) 
{ 
    for (int i = 0; i < nodeList.getLength(); i++) { 
     Node childNode = nodeList.item(i); 
     if (childNode.getNodeName().equals("person")) { 
      //do something with it 
     } 

     NodeList children = childNode.getChildNodes(); 
     if (children != null) 
     { 
      doSomethingWithAll(children); 
     } 
    } 
} 
10

widzę trzy mozliwosci (z których dwa inni odpowiedzieli):

  1. Użyj rekursji.
  2. Użyj XPath (może być nieco przesadny dla tego problemu, ale jeśli masz wiele takich zapytań, to to zdecydowanie coś do odkrycia). Skorzystaj z pomocy kdgregory; szybkie spojrzenie na api wskazywało, że jest to trochę bolesne, aby bezpośrednio używać .
  3. Jeśli co masz jest w rzeczywistości Document (czyli jeśli root jest Document), można użyć Document.getElementsByTagName
+1

+1 - # 3 jest zdecydowanie najprostszym podejściem – kdgregory

+0

+1 dla trzeciego podejścia – NemoStein

0

Oprócz Document.getElementsByTagName() lub XPath, można również użyć jOOX, biblioteka które stworzyłem dla prostszego dostępu do XML i manipulacji. jOOX otacza standardowe interfejsy API języka Java i dodaje metody narzędziowe podobne do jquery. Fragment kodu Python by następnie przełożyć do tego kodu Java:

// Just looking for tag names 
for (Element person : $(tree).find("person")) { 
    personlist.append(person); 
} 

// Use XPath for more elaborate queries 
for (Element person : $(tree).xpath("//person")) { 
    personlist.append(person); 
} 
2

Oto sformatowana wersja:

Element root = xmlData.getDocumentElement(); 
NodeList children = root.getChildNodes(); 

public void doSomethingWithAllToConsole(NodeList nodeList, String tabs) 
{ 
    for(int i=0; i<nodeList.getLength(); i++){ 

     //print current node & values 
     Node childNode = nodeList.item(i); 
     if(childNode.getNodeType()==Node.ELEMENT_NODE){ 
      System.out.print(tabs + childNode.getNodeName()); 
      if(childNode.getFirstChild()!=null 
        && childNode.getFirstChild().getNodeType()==Node.TEXT_NODE 
        && !StringUtil.isNullOrEmpty(childNode.getFirstChild().getNodeValue())){ 
       System.out.print(" = " + childNode.getFirstChild().getNodeValue()); 
      } 
      System.out.println(); 
     } 

     //recursively iterate through child nodes 
     NodeList children = childNode.getChildNodes(); 
     if (children != null) 
     { 
      doSomethingWithAllToConsole(children, tabs+"\t"); 
     } 
    } 
} 
Powiązane problemy