2015-05-22 3 views
0

Я визуализирую файлы XML с javax.swing.JTree. Воспользовавшись кодом от this и this вопроса, я застрял в добавлении атрибутов из узла в виде листов к нему.JTree: Как добавить атрибуты узлов как их собственные листья?

Этот простой XML:

<?xml version="1.0" encoding="utf-8"?> 
<!-- comment --> 
<MYXML xmlns=""> 
    <Header id=""></Header> 
    <Product id="" name=""> 
     <Description>Some text</Description> 
     <Ref id=""></Ref> 
     <Data id=""> 
      <Ref id=""></Ref> 
     </Data> 
     <Form id=""></Form> 
    </Product> 
</MYXML> 

в настоящее время анализируется на org.w3c.dom.Document и передается как org.w3c.dom.Node рекурсивно построить JTree:

private DefaultMutableTreeNode buildTreeNode(Node rootNode) { 
    DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(
      rootNode.getNodeName()); 
    NodeList children = rootNode.getChildNodes(); 

    for (int i = 0; i < children.getLength(); i++) { 
     Node node = children.item(i); 
     short nodeType = node.getNodeType(); 

     if (nodeType == Node.ELEMENT_NODE) { 
      treeNode.add(buildTreeNode(node)); 

      // FIXME attributes should be leaves of their nodes 
      if (node.hasAttributes()) { 
       NamedNodeMap attributes = node.getAttributes(); 
       for (int j = 0; j < attributes.getLength(); j++) { 
        Node attr = attributes.item(j); 
        treeNode.add(new DefaultMutableTreeNode("@" + attr)); 
       } 
      } 
     } else if (nodeType == Node.TEXT_NODE) { 
      String text = node.getTextContent().trim(); 
      if (!text.equals("")) { 
       treeNode.add(new DefaultMutableTreeNode(text)); 
      } 
     } else if (nodeType == Node.COMMENT_NODE) { 
      String comment = node.getNodeValue().trim(); 
      treeNode.add(new DefaultMutableTreeNode("#" + comment)); 
     } 
    } 
    return treeNode; 
} 

Результат не то, что я хотел:

result

Листья «Заголовок», «Реф» и «Форма» должны быть узлами, а все атрибуты (с пометкой @) должны быть листьями их узлов. Как я могу добиться этого с помощью своего рекурсивного подхода?

Вот мой рабочий пример на Gist.

EDIT: Я понял это и ответил на мой вопрос ниже.

+0

Возможно, больше нравится [это] (http://www.developer.com/xml/article.php/3731356/Displaying-XML-in-a-Swing-JTree.htm)? – trashgod

ответ

0

Ну, я, наконец, разобрался, благодаря подсказкам Кшиштофа. Теперь узлы с детьми правильно обрабатываются и атрибуты листьев, где они должны быть:

private DefaultMutableTreeNode buildTreeNode(Node rootNode) { 
    DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(
      rootNode.getNodeName()); 

    if (rootNode.hasAttributes()) { 
     NamedNodeMap attributes = rootNode.getAttributes(); 

     for (int j = 0; j < attributes.getLength(); j++) { 
      String attr = attributes.item(j).toString(); 
      treeNode.add(new DefaultMutableTreeNode("@" + attr)); 
     } 
    } 

    if (rootNode.hasChildNodes()) { 
     NodeList children = rootNode.getChildNodes(); 

     for (int i = 0; i < children.getLength(); i++) { 
      Node node = children.item(i); 
      short nodeType = node.getNodeType(); 

      if (nodeType == Node.ELEMENT_NODE) 
       treeNode.add(buildTreeNode(node)); 

      else if (nodeType == Node.TEXT_NODE) { 
       String text = node.getTextContent().trim(); 
       if (!text.equals("")) 
        treeNode.add(new DefaultMutableTreeNode(text)); 

      } else if (nodeType == Node.COMMENT_NODE) { 
       String comment = node.getNodeValue().trim(); 
       treeNode.add(new DefaultMutableTreeNode("#" + comment)); 
      } 
     } 
    } 
    return treeNode; 

Который производит то, что я хотел:

enter image description here

Для завершения, исправленный пример на Gist.

1

Существует метод isLeaf в TreeNode, вам необходимо реализовать его, потому что он обычно возвращает true, когда этот узел не имеет дочерних элементов (childrenCount == 0) и false в противном случае. Вы хотели бы отметить как элементы узла, независимо от их количества детей, поэтому вам нужно реализовать/переопределить этот метод, чтобы он возвращал то, что вам нужно.

Также есть проблема в вашем алгоритме:

Вы должны проверить, если ваш узел имеет узел детско или только конечный узел с листьями. Вам нужно отличить эти два и внедрить правильную логику для обработки этого, это зависит от вас, как вы интерпретируете этот xml в своем коде.

+0

Спасибо, это сработало. Он работал без вызова 'isLeaf()', поскольку логика основана на узлах документа (я должен был бы назвать «rootNode» на «docNode», чтобы сделать это ясно). – ferkulat