【问题标题】:XML parsing using JAXB使用 JAXB 解析 XML
【发布时间】:2012-12-25 16:45:18
【问题描述】:

我是 xml 解析的新手。我使用 DOM 来解析 xml 以供练习。现在我想将一些移动到其他 xml 解析框架。所以我选择了 JAXB 解析器。对于我的要求,我无法为所有 xml 标签创建 getter setter。因为我将得到的 xml 是动态的。所以我事先不知道创建getter/setter的标签。我参考了这个链接http://www.mkyong.com/java/jaxb-hello-world-example/。有什么方法可以在不创建 getter 和 setter 的情况下进行解析。请让我清楚。

【问题讨论】:

    标签: java xml xml-parsing jaxb xsd


    【解决方案1】:

    Jackson,以其 JSON 处理器而闻名,也有 XML parsing support,它在反射方面做得很好,即使没有 getter 和 setter 也能进行解析。试试看吧。

    【讨论】:

      【解决方案2】:

      对于 JAXB,您应该为可能动态获取的所有 XML 标记创建变量和相应的 getter 和 setter。 如果你有一个标签(你动态地得到的)但你在 Java 类中没有对应的映射变量,那么你会得到 JAXB 异常。

      因此,您可以在 JAXB Java 类中定义一个标签,但在请求中进行,但反过来,一个未在 JAXB 类中定义但在 XML 中定义的标签会给您一个例外。

      【讨论】:

      • 是的,我知道,有没有其他方法可以做或任何其他框架?
      • 我之前也用过XStream,但也有类似JAXB的限制。
      • 默认情况下,JAXB (JSR-222) 实现不会为意外的属性/元素抛出异常。如果您愿意,您可以在 Unmarshaller 上指定自定义 ValidationEventHandler 以实现此目的。您还可以通过在Unmarshaller 上指定Schema 的实例来启用此行为以启用验证。如果您想要未映射的内容,您可以利用@XmlAnyAttribute@XmlAnyElementstackoverflow.com/a/14276830/383861
      • 谢谢@BlaiseDoughan 我不知道,我还有更多问题要问......很长一段时间,我使用的是Java 6 U 37附带的xjc,那么它是否包含在那个版本中?
      • @AurA - 是的 @XmlAnyElement(lax=true) 将包含在该版本中。
      【解决方案3】:

      这将是动态的。解组调用 Customer.setElements;元帅调用 Customer.getElements

      @XmlRootElement
      class Customer {
          @XmlAnyElement
          public void setElements(List<Element> list) {
              for (Element e : list) {
                  String name = e.getNodeName();
                  String value = e.getTextContent();
              }
          }
      
          public List<Element> getElements() throws ParserConfigurationException {
              Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
              List<Element> list = new ArrayList<>();
              Element e = doc.createElement("e1");
              e.setTextContent("v1");
              list.add(e);
              return list;
          }
      }
      

      【讨论】:

      • 我试过这个,在解组时我们需要那个元素的吸气剂,这怎么可能?我试过像 public Element getElement(){ return element; } ...结果为空
      【解决方案4】:

      您可以利用@XmlAnyElementXmlAnyAttribute 注释来映射额外的内容。如果您不想要 get/set 方法,只需在您的课程中添加 @XmlAccessorType(XmlAccessType.FIELD)

      客户

      在下面的类中,我们映射一个特定的 XML 属性和元素,然后使用 @XmlAnyElement 注释映射可能出现的任何其他元素,并使用 @XmlAnyAttribute 映射可能出现的任何其他属性。

      import java.util.*;
      import javax.xml.bind.annotation.*;
      import javax.xml.namespace.QName;
      
      @XmlRootElement
      @XmlAccessorType(XmlAccessType.FIELD)
      public class Customer {
      
          @XmlAttribute
          int id;
      
          @XmlAnyAttribute
          Map<QName, String> otherAttributes;
      
          String name;
      
          @XmlAnyElement(lax=true)
          List<Object> otherElements;
      
      }
      

      input.xml

      我们将在演示代码中解组以下 XML 文档。

      <?xml version="1.0" encoding="UTF-8"?>
      <customer id="123" status="good">
          <name>Jane Doe</name>
          <address>
              <street>1 A Street</street>
              <city>Any Town</city>
          </address>
          <phone-number>555-1111</phone-number>
      </customer>
      

      演示

      以下文档将解组 XML 输入,将所有生成的对象内容转储到 System.out 并将对象编组回 XML。

      import java.io.File;
      import java.util.Map.Entry;
      import javax.xml.bind.*;
      import javax.xml.namespace.QName;
      
      public class Demo {
      
          public static void main(String[] args) throws Exception {
              JAXBContext jc = JAXBContext.newInstance(Customer.class, Address.class);
      
              Unmarshaller unmarshaller = jc.createUnmarshaller();
              File xml = new File("src/forum14272453/input.xml");
              Customer customer  = (Customer) unmarshaller.unmarshal(xml);
      
      
              // Mapped XML Attribute
              System.out.println("customer.id");
              System.out.println("    " + customer.id);
      
              // Other XML Attributes
              System.out.println("customer.otherAttributes");
              for(Entry<QName, String> entry : customer.otherAttributes.entrySet()) {
                  System.out.println("    " + entry);
              }
      
              // Mapped XML Element
              System.out.println("customer.name");
              System.out.println("    " + customer.name);
      
              // Other XML Elements
              System.out.println(customer.otherElements);
              for(Object object : customer.otherElements) {
                  System.out.println("    " + object);
              }
      
              Marshaller marshaller = jc.createMarshaller();
              marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
              marshaller.marshal(customer, System.out);
          }
      
      }
      

      输出

      以下是运行演示代码的输出,请注意所有字段是如何使用 XML 文档中的数据填充的。

      customer.id
          123
      customer.otherAttributes
          status=good
      customer.name
          Jane Doe
      customer.otherElements
          forum14272453.Address@24f454e4
          [phone-number: null]
      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <customer id="123" status="good">
          <name>Jane Doe</name>
          <address>
              <street>1 A Street</street>
              <city>Any Town</city>
          </address>
          <phone-number>555-1111</phone-number>
      </customer>
      

      更多信息

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-21
        • 1970-01-01
        • 2016-05-29
        相关资源
        最近更新 更多