Java Jaxb Unmarshaller如何处理片段XML – XML的部分读取和写入

huangapple go评论110阅读模式
英文:

How does Java Jaxb Unmarshaller handle the fragment xml - the partial reading and writing of xml

问题

这一行会引发异常:

JAXBElement<Fruit> f_file = (JAXBElement<Fruit>) jaxbUnMarshallerFruit.unmarshal(new File("./fruit_in_basket.xml"));

异常的详细信息是:

  1. javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.lin.com/", local:"fruit"). Expected elements are <{http://www.lin.com/}Document>

从异常信息来看,我猜测 Java 的 jaxbUnMarshaller 无法正确解析泛型类的信息。UnMarshaller 不能只解释 Fruit 类。如何修复它?

另外,还有一个小问题:
jaxbContext = JAXBContext.newInstance(Basket.class);
如果我使用 Basket.class,在解组时会出现错误:

unexpected element (uri:"http://www.lin.com/", local:"Document"). Expected elements are (none)

如果我传递 "com.baeldung.springsoap.basket",它可以正常工作。为什么?

(我已经搜索了一段时间,但也许我不能用准确的词语描述我的问题,所以我错过了一些东西。如果可能的话,请提供一些回答的链接。)

英文:

I have a XML file:

  1. &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
  2. &lt;Document xmlns=&quot;http://www.lin.com/&quot;&gt;
  3. &lt;name&gt;basket1&lt;/name&gt;
  4. &lt;fruits id=&quot;1&quot;&gt;
  5. &lt;price&gt;9.99&lt;/price&gt;
  6. &lt;n&gt;Banana&lt;/n&gt;
  7. &lt;/fruits&gt;
  8. &lt;fruits id=&quot;2&quot;&gt;
  9. &lt;price&gt;19.99&lt;/price&gt;
  10. &lt;n&gt;Apple&lt;/n&gt;
  11. &lt;/fruits&gt;
  12. &lt;/Document&gt;

I have entity classes:

  1. package com.baeldung.springsoap.basket;
  2. @XmlType(name = &quot;Document&quot;, propOrder = {&quot;name&quot;, &quot;fruits&quot;})
  3. @XmlAccessorType(XmlAccessType.FIELD)
  4. public class Basket {
  5. @XmlElement(name = &quot;name&quot;)
  6. private String name;
  7. @XmlElement(name = &quot;fruits&quot;, required = true)
  8. private List&lt;Fruit&gt; fruits;
  9. public String getName() {
  10. return name;
  11. }
  12. public void setName(String name) {
  13. this.name = name;
  14. }
  15. public List&lt;Fruit&gt; getFruits() {
  16. return fruits;
  17. }
  18. public void setFruits(List&lt;Fruit&gt; fruits) {
  19. this.fruits = fruits;
  20. }
  21. }
  22. @XmlType(propOrder = {&quot;price&quot;, &quot;name&quot;})
  23. @XmlAccessorType(XmlAccessType.FIELD)
  24. public class Fruit {
  25. @XmlAttribute
  26. int id;
  27. @XmlElement(name = &quot;n&quot;)
  28. String name;
  29. String price;
  30. public int getId() {
  31. return id;
  32. }
  33. public void setId(int id) {
  34. this.id = id;
  35. }
  36. public String getName() {
  37. return name;
  38. }
  39. public void setName(String name) {
  40. this.name = name;
  41. }
  42. public String getPrice() {
  43. return price;
  44. }
  45. public void setPrice(String price) {
  46. this.price = price;
  47. }
  48. }

ObjectFactory.java is:

  1. package com.baeldung.springsoap.basket;
  2. import javax.xml.bind.JAXBElement;
  3. import javax.xml.bind.annotation.XmlElementDecl;
  4. import javax.xml.bind.annotation.XmlRegistry;
  5. import javax.xml.namespace.QName;
  6. @XmlRegistry
  7. public class ObjectFactory {
  8. private final static QName _Document_QNAME = new QName(&quot;http://www.lin.com/&quot;, &quot;Document&quot;);
  9. public Fruit createFruit() {
  10. return new Fruit();
  11. }
  12. @XmlElementDecl(namespace = &quot;http://www.lin.com/&quot;, name = &quot;Document&quot;)
  13. public JAXBElement&lt;Basket&gt; createBasket(Basket value) {
  14. return new JAXBElement&lt;Basket&gt;(_Document_QNAME, Basket.class, null, value);
  15. }
  16. }

package-info.java is:

  1. @javax.xml.bind.annotation.XmlSchema(namespace = &quot;http://www.lin.com/&quot;, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
  2. package com.baeldung.springsoap.basket;

Java unmarshal and marshal code:

  1. public static void run_fruit() {
  2. try {
  3. //jaxbContext = JAXBContext.newInstance(Basket.class); // If I use Basket.class, when unmarshal, it got error: unexpected element (uri:&quot;http://www.lin.com/&quot;, local:&quot;Document&quot;). Expected elements are (none)
  4. JAXBContext jaxbContext = JAXBContext.newInstance(&quot;com.baeldung.springsoap.basket&quot;); //
  5. Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
  6. JAXBElement&lt;Basket&gt; f = (JAXBElement&lt;Basket&gt;) jaxbUnmarshaller.unmarshal(new File(&quot;./basket_fruit.xml&quot;));
  7. // get a piece of fruit info, will save to file later.
  8. Basket bb = f.getValue();
  9. Fruit fruit=bb.getFruits().get(0);
  10. Marshaller jaxbMarshallerFruit = jaxbContext.createMarshaller();
  11. // save a piece of fruit info into file
  12. // in real scenario, we need get a fruit data from list, then save to db as row data.
  13. JAXBElement&lt;Fruit&gt; jaxbFruit= new JAXBElement&lt;&gt;(new QName(&quot;http://www.lin.com/&quot;, &quot;fruits&quot;), Fruit.class, fruit);
  14. jaxbMarshallerFruit.marshal(jaxbFruit, new File(&quot;./fruit_in_basket.xml&quot;));
  15. // read fruit info from file, convert to java object.
  16. Unmarshaller jaxbUnMarshallerFruit = jaxbContext.createUnmarshaller();
  17. JAXBElement&lt;Fruit&gt; f_file = (JAXBElement&lt;Fruit&gt;) jaxbUnMarshallerFruit.unmarshal(new File(&quot;./fruit_in_basket.xml&quot;)); // this line will throw an exception.
  18. System.out.println(f_file);
  19. } catch (JAXBException e) {
  20. e.printStackTrace();
  21. }
  22. }

This line will throw an exception.

  1. JAXBElement&lt;Fruit&gt; f_file = (JAXBElement&lt;Fruit&gt;) jaxbUnMarshallerFruit.unmarshal(new File(&quot;./fruit_in_basket.xml&quot;));

The exception detail is:

  1. javax.xml.bind.UnmarshalException: unexpected element (uri:&quot;http://www.lin.com/&quot;, local:&quot;fruit&quot;). Expected elements are &lt;{http://www.lin.com/}Document&gt;
  2. at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
  3. at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
  4. at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242)
  5. at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)
  6. at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131)
  7. at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556)
  8. at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
  9. at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
  10. at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
  11. at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:374)
  12. at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:613)
  13. at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3132)
  14. at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:852)
  15. at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
  16. at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
  17. at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
  18. at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)
  19. at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)
  20. at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
  21. at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
  22. at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
  23. at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
  24. at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
  25. at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
  26. at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162)
  27. at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171)
  28. at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189)
  29. at com.baeldung.springsoap.xxml.JaxbExampleBasket.run_fruit(JaxbExampleBasket.java:48)
  30. at com.baeldung.springsoap.xxml.JaxbExampleBasket.main(JaxbExampleBasket.java:21)

From the exception, I guess the Java jaxbUnMarshaller can't figure out the authentic generics class info. UnMarshaller can't only interpret Fruit class. How to fix it?

Another minor question is:

  1. jaxbContext = JAXBContext.newInstance(Basket.class);

If I use Basket.class, when unmarshal, it will get an error:

unexpected element (uri:&quot;http://www.lin.com/&quot;, local:&quot;Document&quot;). Expected elements are (none)

If I pass &quot;com.baeldung.springsoap.basket&quot;, it works. Why?

(I have searched for a while, but maybe I can't describe my question with accurate words, so I missed something. If possible, kindly provide some links to the answer.)

答案1

得分: 0

Fruit 类添加 XMLRootElement 应该能消除异常。

  1. @XmlRootElement(name = "fruits")
  2. @XmlType(propOrder = {"price", "name"})
  3. @XmlAccessorType(XmlAccessType.FIELD)
  4. public class Fruit {
  5. // ...
  6. }
英文:

Give the Fruit class an XMLRootElement should eliminate the exception.

  1. @XmlRootElement(name = &quot;fruits&quot;)
  2. @XmlType(propOrder = {&quot;price&quot;, &quot;name&quot;})
  3. @XmlAccessorType(XmlAccessType.FIELD)
  4. public class Fruit {
  5. ....

huangapple
  • 本文由 发表于 2023年3月7日 18:23:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75660712.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定