gpt4 book ai didi

java - 从子元素开始使用 JAXB 解码

转载 作者:行者123 更新时间:2023-11-30 06:16:41 25 4
gpt4 key购买 nike

我正在尝试使用 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>

我想从用户元素开始解码 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");
}

}

最佳答案

JAXB 解码完整的 XML,@XmlRootElement(name = "user") 不会过滤“您在 XML 中看到的第一个 user 元素”。

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

  • 最简单的方法可能是解码完整的 XML,然后从结果结构中检索 user 对象。
  • 另一种选择是使用 StAX。请参阅this article by Blaise Doughan关于如何做到这一点。
  • 您还可以预先过滤使用 SAX 解析的 XML,但这可能并不那么容易。
  • 最后,您可以先将 XML 解析为 DOM,找到所需的 user 节点并解码该节点。

如果 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();

(从 this article 复制粘贴并进行一些调整,根本没有测试。)

感谢Blaise Doughan .

关于java - 从子元素开始使用 JAXB 解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49056925/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com