2

我正在尝试解组给定的 XML:

<FHcomment>
 <TX>rewriting of file</TX>
 <tool_id>toolA</tool_id>
 <tool_vendor>Company</tool_vendor>
 <tool_version>1.7.36.0</tool_version>
</FHcomment>

该模式已编译为 JAXB 类,请参见此处:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
 "tx",
 "toolId",
 "toolVendor",
 "toolVersion",
 "userName",
 "commonProperties",
 "extensions"
})
@XmlRootElement(name = "FHcomment")
public class FHcomment {

@XmlElement(name = "TX", required = true)
protected TX tx;
@XmlElement(name = "tool_id", required = true)
protected BaseName toolId;
@XmlElement(name = "tool_vendor", required = true)
protected BaseName toolVendor;
@XmlElement(name = "tool_version", required = true)
protected BaseVersion toolVersion;
@XmlElement(name = "user_name")
protected BaseName userName;
@XmlElement(name = "common_properties")
protected CommonPropertiesType commonProperties;
protected ExtensionsType extensions;
@XmlAnyAttribute
private Map<QName, String> otherAttributes = new HashMap<QName, String>();

.....
/*
 * GETTERS and SETTERS for the fields have been removed here
 */
.....
}

我解组 XML 的代码如下:

JAXBContext jc = JAXBContext.newInstance(FHcomment.class);
String s = "<FHcomment>....</Fhcomment>";
Unmarshaller unmarshaller = jc.createUnmarshaller();
XMLInputFactory fac = XMLInputFactory.newFactory();
XMLStreamReader xsr = fac.createXMLStreamReader(new StringReader(s));
JAXBElement<FHcomment> foo = unmarshaller.unmarshal(xsr, FHcomment.class);
FHcomment val = foo.getValue();

问题:生成的 FHcomment 对象不包含 FHcomment 的子元素。全部为空,这不是所需的结果。

如何告诉 JAXB 将给定的 XML 完全解组为对象?

编辑:将 ValidationHandler 添加到 Unmsarshaller 后,我更接近问题:

意外元素(uri:“”,本地:“TX”)。预期的元素是 <{htp://www.example.com/mdf/v4}tool_id>、<{htp://www.example.com/mdf/v4}TX>、<{htp://www.www .example.com/mdf/v4}common_properties>,<{htp://www.example.com/mdf/v4}tool_version>,<{htp://www.example.com/mdf/v4}extensions>, <{htp://www.www.example.com/mdf/v4}tool_vendor>,<{htp://www.www.example.com/mdf/v4}user_name>

意外元素(uri:“”,本地:“tool_id”)。预期的元素是......

事实证明,JAXB 不喜欢提供的 XML 不包含命名空间信息的事实。那么我如何告诉解组器忽略命名空间?

编辑2:

经过更多研究后,我找不到一种方法来欺骗 JAXB 在没有命名空间验证的情况下工作。我使用http://cooljavablogs.blogspot.de/2008/08/how-to-instruct-jaxb-to-ignore.html上的教程来规避我的问题。不是一个很好的解决方案,但最好的解决方案......

4

4 回答 4

3

您的 XML 文档与映射中定义的名称空间限定不匹配(请参阅: http ://blog.bdoughan.com/2010/08/jaxb-namespaces.html )。在解组操作期间,您可以利用XMLFilter一个名称空间将名称空间应用于您的 XML 文档。

import org.xml.sax.*;
import org.xml.sax.helpers.XMLFilterImpl;

public class NamespaceFilter extends XMLFilterImpl {

    private static final String NAMESPACE = "htp://www.example.com/mdf/v4";

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        super.endElement(NAMESPACE, localName, qName);
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes atts) throws SAXException {
        super.startElement(NAMESPACE, localName, qName, atts);
    }

}

XMLFilter下面是一个在解组期间如何利用的示例。

    // 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("input.xml");
    filter.parse(xml);
    Object result = unmarshallerHandler.getResult();

了解更多信息

于 2013-06-20T14:56:09.490 回答
0

你是如何注释类 BaseName 、 BaseVersion 和 TX 的?

如果您没有对这些类进行注释,则将这些类中的 String 注释为 @XmlValue

于 2013-06-26T13:28:59.943 回答
0

尝试删除以下代码,然后重试:

  @XmlType(name = "", propOrder = {
     "tx",
     "toolId",
     "toolVendor",
     "toolVersion",
     "userName",
     "commonProperties",
     "extensions"
    })
于 2013-06-20T13:40:15.647 回答
0

BaseName将and更改TX为 String ,它应该可以工作。因为它是 xml 不符合您的模式,在这种情况下由类表示。

于 2013-06-20T13:36:02.997 回答