JAXB: Почему значение возвращает ноль, если я просто устанавливаю это значение, и возвращает реальное значение, когда я устанавливаю другие значения? - PullRequest
1 голос
/ 14 марта 2012

У меня есть генератор java-класса из схемы xsd с JAXB.В классе Main у меня есть метод с именем recursiveNodeList(NodeList list), который просто берет список узлов и рекурсивно просматривает его, чтобы получить из него все значения.

Все работает, кроме одной вещи, которую я просто не могу понять.

В приведенном ниже коде у меня есть эти две строки:

item.setNote("Notetest1");
item.setTitle("Title1");

Когда я запускаю код, я получаю этот вывод:

title->#text->Title1
note->#text->Notetest1

Если я просто использую одну изстроки, например:

item.setNote("Notetest1");
// item.setTitle("Title1"); /*commented out*/

Я получаю этот вывод:

item->note->null

Почему примечание является нулевым, если я просто устанавливаю это значение и не вызываю setTitle() и почему оно имеетзначение, когда я вызываю setNote и setTitle?

Код в целом:

public class JavaXML {

    public static void main(String[] args) throws ParserConfigurationException, JAXBException, FileNotFoundException {
        Item item = new Item();

        JAXBContext jaxb = JAXBContext.newInstance(item.getClass().getPackage().getName());        
        Marshaller marshaller = jaxb.createMarshaller();
        item.setNote("Notetest1");
        item.setTitle("Title1");


        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.newDocument();
        marshaller.marshal(item, doc);

        NodeList nodeList = doc.getChildNodes();
        recursiveNodeList(nodeList);

    }

    public static void recursiveNodeList(NodeList nodeList) {
        for(int i = 0; i< nodeList.getLength(); i++) {
            Node fstNode = nodeList.item(i);
            if (fstNode.getNodeType() == Node.ELEMENT_NODE) {             
                Element fstElmnt = (Element) fstNode;

                if(fstElmnt.getChildNodes().getLength() > 1) {
                    NodeList fstNmElmntLst = fstElmnt.getChildNodes();
                    recursiveNodeList(fstNmElmntLst);
                } else {
                    NodeList fstNmElmntLst = fstElmnt.getChildNodes();
                    if(((Node)fstNmElmntLst.item(0)) != null)
                        System.out.println(fstNode.getNodeName()+"->"+((Node)fstNmElmntLst.item(0)).getNodeName() + "->"+((Node)fstNmElmntLst.item(0)).getNodeValue());
                }
            }
        }
    }
}

РЕДАКТИРОВАТЬ

Еще один вопрос:Если я вместо установки заголовка и заметки, установите категорию следующим образом:

Category category = new Category();
category.setStringOne("string1");
category.setStringTwo("string2");
item.setCategory(category);

Тогда вывод будет:

item->category->string1string2

Есть ли способ получить "string1"и значения "string2" в отдельные переменные без использования методов манипуляции со строками?

1 Ответ

1 голос
/ 14 марта 2012

Ошибка в вашем recursiveNodeList методе.В случае с одним элементом вы попали на строку System.out.println с узлом Element, а в случае с двумя элементами вы попали на строку System.out.println с узлом Text.Код ниже будет работать, но, вероятно, нуждается в очистке.

public static void recursiveNodeList(NodeList nodeList) {
    for(int i = 0; i< nodeList.getLength(); i++) {
        Node fstNode = nodeList.item(i);
        if (fstNode.getNodeType() == Node.ELEMENT_NODE) {             
            Element fstElmnt = (Element) fstNode;

            if(fstElmnt.getChildNodes().getLength() > 1) {
                NodeList fstNmElmntLst = fstElmnt.getChildNodes();
                recursiveNodeList(fstNmElmntLst);
            } else {
                NodeList fstNmElmntLst = fstElmnt.getChildNodes();
                Node node = fstNmElmntLst.item(0);
                if(node != null)
                    if(node.getNodeType() == Node.ELEMENT_NODE) {
                        System.out.println(fstNode.getNodeName()+"->"+node.getNodeName() + "->"+((Element)node).getTextContent());
                    } else {
                        System.out.println(fstNode.getNodeName()+"->"+node.getNodeName() + "->"+node.getNodeValue());
                    }
                }
            }
        }
    }
}

ОБНОВЛЕНИЕ

Ваша реализация JAXB (JSR-222) правильно создает документ.Исходные и обновленные ошибки, которые вы видите, связаны с тем, как вы обрабатываете узлы DOM в recursiveNodeList.Если вы заинтересованы в продолжении этого подхода, я бы рекомендовал пройтись по коду и обратить внимание на то, когда текущий узел соответствует тегу (т.е. note) и имеет тип Element, и когда он соответствует тексту (например, Notetest1) и имеет тип Text.Ниже я привел новый пример кода, который использует XPath для анализа документа, который вам может показаться более простым в использовании.

package forum9698306;

import javax.xml.bind.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;    
import org.w3c.dom.*;

public class JavaXML {

    public static void main(String[] args) throws Exception {
        Item item = new Item();

        JAXBContext jaxb = JAXBContext.newInstance(item.getClass().getPackage().getName());        
        Marshaller marshaller = jaxb.createMarshaller();
        item.setNote("Notetest1");
        item.setTitle("Title1");

        Category category = new Category();
        category.setStringOne("string1");
        category.setStringTwo("string2");
        item.setCategory(category);

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.newDocument();
        marshaller.marshal(item, doc);

        XPathFactory xpf = XPathFactory.newInstance();
        XPath xpath = xpf.newXPath();
        System.out.println(xpath.evaluate("item/note/text()", doc, XPathConstants.STRING));
        System.out.println(xpath.evaluate("item/title/text()", doc, XPathConstants.STRING));
        System.out.println(xpath.evaluate("item/category/stringOne/text()", doc, XPathConstants.STRING));
        System.out.println(xpath.evaluate("item/category/stringTwo/text()", doc, XPathConstants.STRING));
    }

}

Вывод

Notetest1
Title1
string1
string2
...