如何让 JAXB 解组器忽略前缀? [英] How to make JAXB unmarshaller to ignore prefixes?

查看:32
本文介绍了如何让 JAXB 解组器忽略前缀?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下 XML:

<ns2:Person name="John" age="20" />

我想将它解组为从 XSD 生成的 JAXB 对象 Person.

And I want to unmarshal it to JAXB object Person which was generated from the XSD.

这是我正在运行的代码:

this is the code I'm running:

JAXBContext context = JAXBContext.newInstance(PersoEntity.class);
Unmarshaller um = context.createUnmarshaller();
StringReader sr = new StringReader(xml);
Person p = (Person)um.unmarshal(sr);

令人惊讶的是,我收到以下异常:

Surprisingly I get the following exception:

javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException: The prefix "ns2" for element "ns2:Person" is not bound.]

我该如何解决?谢谢

推荐答案

获取碎片

您当前获取 XML 片段的方式导致名称空间声明丢失.在您的片段中,ns2 不再是前缀,您只有一个带有冒号的元素名称 (ns2:Person).这将导致命名空间感知解析器出现问题.下面的文章可能是您获取 XML 片段的更好方法:

The way that you are currently getting the XML fragment is causing the namespace declarations to be lost. In your fragment ns2 is no longer a prefix, you just have a element name with a colon in it (ns2:Person). This is going to cause problems with namespace aware parsers. The article below may be a better approach for you to get the XML fragment:

处理您的用例

使用您拥有的 XML 片段,您可以创建一个 XMLFilter 从 XML 元素中删除前缀,然后利用 JAXB 的 UnmarshallerHandler 进行解组.

Using the XML fragment that you have, you could create an XMLFilter that removes the prefix from the XML element, and then leverage JAXB's UnmarshallerHandler to do the unmarshalling.

演示

package forum11968399;

import java.io.StringReader;
import javax.xml.bind.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.XMLFilterImpl;

public class Demo {

    private static final String xml = "<ns2:Person name='John' age='20' />";

    public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XMLReader xmlReader = sp.getXMLReader();
        XMLFilter xmlFilter = new MyXMLFilter(xmlReader);

        JAXBContext context = JAXBContext.newInstance(PersonEntity.class);
        Unmarshaller um = context.createUnmarshaller();
        UnmarshallerHandler unmarshallerHandler = um.getUnmarshallerHandler();
        xmlFilter.setContentHandler(unmarshallerHandler);

        StringReader sr = new StringReader(xml);
        xmlFilter.parse(new InputSource(sr));
        PersonEntity p = (PersonEntity) unmarshallerHandler.getResult();
    }

    private static class MyXMLFilter extends XMLFilterImpl {

        public MyXMLFilter(XMLReader xmlReader) {
            super(xmlReader);
        }

        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            int colonIndex = qName.indexOf(':');
            if(colonIndex >= 0) {
                qName = qName.substring(colonIndex + 1);
            }
uri = XML_NAMESPACE; //to prevent unknown XML element exception, we have to specify the namespace here
            super.startElement(uri, localName, qName, attributes);
        }

        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            int colonIndex = qName.indexOf(':');
            if(colonIndex >= 0) {
                qName = qName.substring(colonIndex + 1);
            }
            super.endElement(uri, localName, qName);
        }

    }

}

PersonEntity

package forum11968399;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="Person")
@XmlAccessorType(XmlAccessType.FIELD)
public class PersonEntity {

    @XmlAttribute
    private String name;

    @XmlAttribute
    private int age;

}

这篇关于如何让 JAXB 解组器忽略前缀?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆