简体   繁体   English

JAXB:如果我只设置一个值,为什么一个值返回null,而设置其他值时为什么返回一个实值?

[英]JAXB: Why does a value return null if I just set that value, and returns a real value when I set other values?

I have generadet a java class from a xsd schema with JAXB . 我已经使用JAXB从xsd模式生成了java类。 In the the Main class I have a method called recursiveNodeList(NodeList list) that just takes a node list and iterates through it recursivly to get all values out of it. 在Main类中,我有一个称为recursiveNodeList(NodeList list)的方法,该方法只获取一个节点列表并递归地对其进行迭代以获取所有值。

Everything works except one thing that I cannot simply understand. 除了我无法简单理解的一件事以外,其他所有东西都起作用。

In the code below I have these two lines: 在下面的代码中,我有这两行:

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

When I run the code I get this output: 当我运行代码时,我得到以下输出:

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

If I just use one of the lines, like: 如果我只使用其中之一,例如:

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

I get this output: 我得到以下输出:

item->note->null

Why is the note null if I just set that value and not call setTitle() and why does it have a value when I call both setNote and setTitle? 如果仅设置该值而不调用setTitle() ,为什么注释为null;为什么当我同时调用setNotesetTitle?时,该注释具有值setTitle?

The code in its whole: 整个代码:

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());
                }
            }
        }
    }
}

EDIT 编辑

Another question: If I instead of setting the title and note, set the category like this: 另一个问题:如果我不设置标题和注释,则设置如下类别:

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

Then the output would be: 那么输出将是:

item->category->string1string2

Is there any way to get the "string1" and "string2" values into separate variables without using string manipulation techniques? 有没有办法在不使用字符串操作技术的情况下将“ string1”和“ string2”值转换为单独的变量?

The error is in your recursiveNodeList method. 该错误在您的recursiveNodeList方法中。 In the single element case you were hitting the System.out.println line with an Element node, and in the two element case you were hitting the System.out.println line with a Text node. 在单元素情况下,您将使用Element节点命中System.out.println行,而在两个元素情况下,您将使用Text节点命中System.out.println行。 The code below will work, but probably needs cleaned up. 下面的代码可以工作,但是可能需要清理。

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());
                    }
                }
            }
        }
    }
}

UPDATE UPDATE

Your JAXB (JSR-222) implementation is creating the document correctly. 您的JAXB(JSR-222)实现正确创建了文档。 The original and updated errors you are seeing are due to the way you are processing the DOM nodes in recursiveNodeList. 您看到的原始错误和更新错误是由于您处理recursiveNodeList中的DOM节点的方式引起的。 If you are interested in continuing with that approach I would recommend stepping through the code and paying attention to when the current node corresponds to a tag (ie note ) and is of type Element, and when it corresponds to text (ie Notetest1 ) and is of type Text. 如果您有兴趣继续使用该方法,建议您单步执行代码,并注意当前节点何时对应于标签(即note )和类型为Element,以及何时其对应于文本(即Notetest1 )并且为类型为文本。 Below I have given a new code example that uses XPath to introspect the document which you may find easier to use. 下面,我给出了一个新的代码示例,该示例使用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));
    }

}

Output 输出量

Notetest1
Title1
string1
string2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM