当前位置: 首页 > 知识库问答 >
问题:

使用JAXB从子元素开始解组

邹举
2023-03-14

我正在尝试使用JAXB以以下格式散集XML:

<return_data api_call="getuser">
    <users>
       <user>
          <username>test_me</username>
          <account_expiration_date>0000-00-00</account_expiration_date>        
       </user>
    </users>
</return_data>

我想从user元素开始解组XML。但是,当我尝试使用“@XmlRootElement(name=“user”)”时,我收到以下错误:

Exception in thread "main" java.lang.RuntimeException: Unable to parse XML:
    at com.example.findAccount(AccountService.java:30)
    at com.example.main(AccountService.java:50)
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"return_data"). Expected elements are <{}user>
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:379)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:605)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3138)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:880)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171)
    at com.example.findAccount(AccountService.java:26)
    ... 1 more

这是我的帐户模型类:

package com.example;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "user")
public class Account {

    private String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

服务:

package com.example;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Optional;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import com.example.Account;

public class AccountService {

    public Optional<Account> findAccount(final String username) {

        try {
            URL url = new URL("https://example.com/foo/bar" + username);
            JAXBContext jaxbContext = JAXBContext.newInstance(Account.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            Account account = (Account) jaxbUnmarshaller.unmarshal(url);

            return Optional.ofNullable(account);
        } catch (JAXBException | MalformedURLException e) {
            throw new RuntimeException("Unable to parse XML:", e);
        }
    }

    public static void main(String[] args) {
        // test it //
        new AccountService().findAccount("user");
    }

}

共有1个答案

郎玮
2023-03-14

JAXB解组完整的XML,< code > @ xmlroot element(name = " user ")不会过滤“您在XML中看到的第一个< code>user元素”。

如果您想要这个(“在XML中看到的第一个user元素”),有几个选项。

  • 最简单的方法可能是解组整个XML,然后从结果结构中检索user对象
  • 另一种选择是使用StAX。请参阅Blaise Doughan的这篇文章,了解如何做到这一点
  • 您还可以使用SAX对解析的XML进行预过滤,但这可能并不容易
  • 最后,您可以首先将XML解析为DOM,找到所需的user节点并解组该节点

如果用户元素周围没有太多的 XML,我只会解析完整的 XML。否则,我会选择StAX选项。这将是沿着这条线的东西:

    XMLInputFactory xif = XMLInputFactory.newFactory();
    StreamSource xml = new StreamSource("https://example.com/foo/bar" + username);
    XMLStreamReader xsr = xif.createXMLStreamReader(xml);
    xsr.nextTag();
    while(!xsr.getLocalName().equals("user")) {
        xsr.nextTag();
    }

    JAXBContext jc = JAXBContext.newInstance(Account.class);
    Unmarshaller unmarshaller = jc.createUnmarshaller();
    JAXBElement<Account> jb = unmarshaller.unmarshal(xsr, Account.class);
    xsr.close();

    Account user = jb.getValue();

(复制粘贴自本文,稍加调整,完全未经测试。)

向布莱斯·道昂致敬。

 类似资料:
  • 我正在编写一个解组器,我正在努力与jaxb进行斗争,以获得一个有效的解决方案。 我想解组从生成的MessageDescription。wsdl文件。wsdl文件中的java类是: 由于没有@XmlRootElement,我用包装器扩展了类,并自己添加了注释 我使用我的“包装器”MessageDescription类来解组 解组过程正在工作,但有一个子项始终设置为null。我不知道在哪里可以修复这个

  • 背景: 我使用JAXB将XML解组为Java对象。最初,我只是使用JAXB来执行解组。然后对代码进行静态分析,并提出了XML外部实体注入的高关键性问题。经过一点研究,我发现了一个建议(https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#JAXB_Unmarshaller)使用配置为防止解析

  • 我正在尝试解组一个包含多个同名元素的XML文档。我不确定是否需要创建bean的Arraylist并将其传递给解组器。我希望有人能给我一些建议来解决这个问题。我试图解析的XML是一个SOAP响应,但我去掉了信封,所以我只有它的主体,它看起来是这样的: 这是从一个包含50多个字段的表返回的,但我创建了一个testBean,并且我定义了fkdevice只是为了使其简单,我的bean看起来像这样: 这给了

  • myType也被定义为complexType。然后得到生成的类MyResponse.java和Reference.java。我可以通过以下方式分配“引用”的值: 而且奏效了。 现在我只是删除了maxOccurs=“unbounded”,它不再起作用了。响应不再是List类型,而是JaxBelement类型。我试着用: 谁能告诉我,当它不是一个列表时,什么是正确的做法?

  • 你好,我正在使用JAXB将XML解锁到JAVA,我的xml文档中有一个元素“值”,可以是int类型,也可以是双精度型,并且我的java类中此元素的相应属性是数字类型的“值”。 JAXB不支持“数字”类型的umarshaling,我想,有人知道如何处理这个问题吗?一个例子将会得到真正的赞赏。提前谢谢。

  • 我目前正在学习如何在android中使用Jaxb解析xml文件。但是我不知道代码中有什么错误,以及在哪里和如何纠正它。我无法解析xml并获得食品列表。如果我删除List并简单地把它写成Food,那么只有xml中的最后一个元素被解析,其余的似乎都被覆盖了。请帮助我。 我试图解析http://www.w3schools.com/xml/simple.xml,,目前我有这样的代码: ---- 用于取消