[英]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;为什么当我同时调用setNote
和setTitle?
时,该注释具有值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.