我有
@XmlRootElement(namespace = "http://www.w3.org/2005/Atom", name = "content")
@XmlType(name = "course")
public class Course implements Resource
...
@XmlElementWrapper(name="subcourses")
@XmlElement(name="course")
List<Xlink> subcourses; //!?
和Xlink类,该类在内联变量中工作良好。
public class Xlink
{
private String href;
private String value;
@XmlAttribute(namespace = "http://www.w3.org/1999/xlink")
public String getHref()
{
return href;
}
public void setHref(String href)
{
this.href = href;
}
@XmlValue
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = value;
}
}
对于的XML输入
<atom:content atom:type="xml" xsi:type="course">
...
<subcourses>
<course xlink:href="course1">Some course</course>
<course xlink:href="course2">other course</course>
并且子课程拒绝被取消注册(没有任何异常被抛出)。
注:不幸的是,MOXy不是一个选项。
编辑:新编组对象
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:content xmlns:ns2="http://www.w3.org/1999/xlink" xmlns:ns3="http://www.w3.org/2005/Atom">
<code>SOME CODE</code>
<name>name</name>
<subcourses>
<course ns2:href="Some href">some value</course>
<course ns2:href="sdsdg">sdfhdfhdhdh</course>
</subcourses>
</ns3:content>
Edit2:在对测试对象进行了一些解组和编组的实验之后,我发现我需要在内容的标题中定义xmlns名称空间,以便与xlink:href=
类似xmlns:xlink=”http://www.w3.org/1999/xlink“
问题在于,我从一个包装类中获取Course元素,该包装类由resteasy解析出来。因此,生成的类不会携带名称空间信息。
不知何故,我需要强迫JAXB理解xmlns: xlink="http://www.w3.org/1999/xlink"适用于课程元素,但是经过一个小时的谷歌搜索,我不知所措。
编辑3:我得到我的对象从
https://github.com/jirutka/atom-jaxb/blob/master/src/main/java/cz/jirutka/atom/jaxb/Entry.java
在对应的服务器上使用。这反过来又是
https://github.com/jirutka/atom-jaxb/blob/master/src/main/java/cz/jirutka/atom/jaxb/Feed.java
我的解组代码的相关部分包括:
Feed f = r.readEntity(Feed.class);
out.addAll(unmarshaller.Unmarshal(f.getEntries(), clazz));
其中r是一个javax.ws.rs.core.响应。还有解组员
public List<T> Unmarshal(List<Entry> entries, Class clazz)
{
List<T> out = new ArrayList<T>();
T instance;
for (Entry e : entries)
{
try
{
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller unmarsh = context.createUnmarshaller();
instance = (T) unmarsh.unmarshal((Node) e.getContent());
因为这是我第一次纠结于这项技术,所以这段代码完全有可能是“wtf”。
注释字段(实例变量)时,请确保将@XmlAccessorType(XmlAccessType)。字段)
在你的类上。
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement(namespace = "http://www.w3.org/2005/Atom", name = "content")
@XmlAccessorType(XmlAccessType.FIELD)
public class Course implements Resource {
@XmlElementWrapper(name = "subcourses")
@XmlElement(name = "course")
List<Xlink> subcourses;
}
然后确保您的XML输入正确地限定了名称空间。您的输入文档应如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<atom:content xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:atom="http://www.w3.org/2005/Atom">
<code>SOME CODE</code>
<name>name</name>
<subcourses>
<course xlink:href="Some href">some value</course>
<course xlink:href="sdsdg">sdfhdfhdhdh</course>
</subcourses>
</atom:content>
有了我更新的课程
类、您的Xlink
类和一个正确的名称空间限定的XML文档,下面的演示代码对我来说非常适合。
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Course.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum17766166/input.xml");
Course course = (Course) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(course, System.out);
}
}
更新#1
Edit2:在对测试对象进行了一些解组和编组的实验之后,我发现我需要在内容的标题中定义xmlns名称空间,以匹配xlink:href=like xmlns:xlink=”http://www.w3.org/1999/xlink“问题是,我从一个包装类中获取Course元素,这个包装类由resteasy解析出来。因此,生成的类不会携带名称空间信息。
修复问题的最佳位置是提取要解除marhal的片段。下面是一个可以与StAX一起使用的策略。
输入xml
下面是一个示例XML文档,其中名称空间信息定义在要解组的片段上方。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:atom="http://www.w3.org/2005/Atom">
<bar>
<atom:content>
<code>SOME CODE</code>
<name>name</name>
<subcourses>
<course xlink:href="Some href">some value</course>
<course xlink:href="sdsdg">sdfhdfhdhdh</course>
</subcourses>
</atom:content>
</bar>
</foo>
演示
下面我们将使用StAXXMLStreamReader
导航到目标片段。我们将让JAXB实现散集这个片段。这样就保留了所有的命名空间信息。
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Course.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
StreamSource source = new StreamSource("src/forum17766166/input.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(source);
while(xsr.hasNext()) {
if(xsr.isStartElement() && "content".equals(xsr.getLocalName())) {
break;
}
xsr.next();
}
Unmarshaller unmarshaller = jc.createUnmarshaller();
Course course = (Course) unmarshaller.unmarshal(xsr);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(course, System.out);
}
}
输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:content xmlns:ns2="http://www.w3.org/1999/xlink" xmlns:ns3="http://www.w3.org/2005/Atom">
<subcourses>
<course ns2:href="Some href">some value</course>
<course ns2:href="sdsdg">sdfhdfhdhdh</course>
</subcourses>
</ns3:content>
更新#2
如果您无法生成更新#1中所述的更好的XML片段,下面是如何修复您当前拥有的XML片段。
名称空间过滤器
您可以使用SAXXMLFilter
来修复XML文档。
import org.xml.sax.*;
import org.xml.sax.helpers.*;
public class NamespaceFilter extends XMLFilterImpl {
private static final String ATOM_URI = "http://www.w3.org/2005/Atom";
private static final String XLINK_URI = "http://www.w3.org/1999/xlink";
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
if("atom:content".equals(qName)) {
super.startElement(ATOM_URI, "content", qName, atts);
} else if("course".equals(qName)) {
AttributesImpl modifiedAtts = new AttributesImpl();
modifiedAtts.addAttribute(XLINK_URI, "href", "xlink:href", null, atts.getValue(0));
super.startElement(uri, localName, qName, modifiedAtts);
} else {
super.startElement(uri, localName, qName, atts);
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if("atom:content".equals(qName)) {
super.endElement(ATOM_URI, "content", qName);
} else {
super.endElement(uri, localName, qName);
}
}
}
演示
下面是如何利用JAXB的XmlFilter
:
import javax.xml.bind.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Course.class);
// Create the XMLFilter
XMLFilter filter = new NamespaceFilter();
// Set the parent XMLReader on the XMLFilter
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
filter.setParent(xr);
// Set UnmarshallerHandler as ContentHandler on XMLFilter
Unmarshaller unmarshaller = jc.createUnmarshaller();
UnmarshallerHandler unmarshallerHandler = unmarshaller
.getUnmarshallerHandler();
filter.setContentHandler(unmarshallerHandler);
// Parse the XML
InputSource xml = new InputSource("src/forum17766166/input.xml");
filter.parse(xml);
Course course = (Course) unmarshallerHandler.getResult();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(course, System.out);
}
}
了解更多信息
更新#3
下面是示例代码的简化版本,其中所有内容都有效。也许你的代码中有一些不同的东西,它会帮助你找到。
进入
import javax.xml.bind.annotation.*;
@XmlRootElement(namespace="http://www.w3.org/2005/Atom")
@XmlAccessorType(XmlAccessType.FIELD)
public class Entry<T> {
@XmlElement(namespace = "http://www.w3.org/2005/Atom")
@XmlSchemaType(name = "atomInlineOtherContent")
private T content;
public T getContent() {
return content;
}
}
输入xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<atom:entry xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:atom="http://www.w3.org/2005/Atom">
<atom:content>
<code>SOME CODE</code>
<name>name</name>
<subcourses>
<course xlink:href="Some href">some value</course>
<course xlink:href="sdsdg">sdfhdfhdhdh</course>
</subcourses>
</atom:content>
</atom:entry>
演示
import java.io.File;
import javax.xml.bind.*;
import org.w3c.dom.Node;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Entry.class, Course.class);
// Unmarshal Entry
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum17766166/input.xml");
Entry entry = (Entry) unmarshaller.unmarshal(xml);
// Unmarshal Course
Node contentNode = (Node) entry.getContent();
Course course = (Course) unmarshaller.unmarshal(contentNode);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(course, System.out);
}
}
输出
<?xml version="1.0" encoding="UTF-8"?>
<ns0:content xmlns:ns1="http://www.w3.org/1999/xlink" xmlns:ns0="http://www.w3.org/2005/Atom">
<subcourses>
<course ns1:href="Some href">some value</course>
<course ns1:href="sdsdg">sdfhdfhdhdh</course>
</subcourses>
</ns0:content>
当在testng单元testcase中运行时,JAXB将XML文件解组到对象中工作正常。 当相同的代码被用来在另一个进程中解封相同的XML文件时,我得到了一个空对象。我可以验证对象是为XML文档中的每个元素创建的,并且所有适配器都被调用。在unmarshaller中设置事件处理程序,但没有验证问题。当我设置xmlns属性和前缀时,即使返回空对象,行为也略有不同。 我看了好几篇文章,但都无法与我面临
我有如下所示的XML: 我有一个ObjectList类,它如下所示: 和如下所示的对象类: 当我尝试使用以下代码将xml解封到and对象中时: 我得到以下错误: UnMarshalException:意外元素(URI:“”,本地:“ObjectList”)。需要的元素为<{}Object>、<{}ObjectList> 编辑:我刚刚注意到两个问题我将我的ObjectList对象的XmlRootEl
错误中的SOAP WSDL URL是Spring Boot应用程序中的另一个web服务。试图理解为什么这会出现在错误中。 UnmarshalException:意外元素(URI:“”,local:“message”)。需要的元素是<{http://soap_wsdl_url}jaxb_pojo_name>
我对JAXB很陌生,在解封一般对象时遇到了麻烦。问题是我需要能够封送和解封任何对象(java.lang.object)。我成功地进行了封送处理,但是当我运行解封处理时,响应中得到的是一个“ElementNSimpl”对象,而不是我自己的对象。 这是涉及的bean: message.java somebean.java jaxb.index的内容: 生成的xml很好()但是在解封后计算“msg.ge
问题内容: 我有一个返回此XML的服务: 要么 我想使用以下类解组检索到的XML: 结果 : 项目名称 : 用户名 : 首先不起作用的解决方案 我得到一个空名单。 第二不起作用的解决方案 受本文启发,http://blog.bdoughan.com/2012/11/creating-generic-list-wrapper-in- jaxb.html 我修改了Response类: 然后使用以下代码
我使用cxf的jaxb来解封xml请求。 我正在寻找一种验证输入xml请求的方法,我已经阅读了下面两篇关于验证的超级文章,但它们并不是我所需要的。 http://blog.bdoughan.com/2010/11/validate-jaxb-object-model-with-xml.html http://blog.bdoughan.com/2010/12/jaxb-and-marshalunm