java - JAXB:如何在解码 XML 文档期间忽略命名空间?

标签 java xml xml-serialization jaxb

我的架构指定了一个命名空间,但文档没有。在 JAXB 解码(XML -> 对象)期间忽略命名空间的最简单方法是什么?

换句话说,我有

<foo><bar></bar></foo>

而不是,

<foo xmlns="http://tempuri.org/"><bar></bar></foo>

最佳答案

这是 VonCs 解决方案的扩展/编辑,以防万一有人不想经历实现自己的过滤器的麻烦来执行此操作。它还展示了如何在不存在 namespace 的情况下输出 JAXB 元素。这一切都是使用 SAX 过滤器完成的。

过滤器实现:

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import org.xml.sax.helpers.XMLFilterImpl;

public class NamespaceFilter extends XMLFilterImpl {

    private String usedNamespaceUri;
    private boolean addNamespace;

    //State variable
    private boolean addedNamespace = false;

    public NamespaceFilter(String namespaceUri,
            boolean addNamespace) {
        super();

        if (addNamespace)
            this.usedNamespaceUri = namespaceUri;
        else 
            this.usedNamespaceUri = "";
        this.addNamespace = addNamespace;
    }



    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        if (addNamespace) {
            startControlledPrefixMapping();
        }
    }



    @Override
    public void startElement(String arg0, String arg1, String arg2,
            Attributes arg3) throws SAXException {

        super.startElement(this.usedNamespaceUri, arg1, arg2, arg3);
    }

    @Override
    public void endElement(String arg0, String arg1, String arg2)
            throws SAXException {

        super.endElement(this.usedNamespaceUri, arg1, arg2);
    }

    @Override
    public void startPrefixMapping(String prefix, String url)
            throws SAXException {


        if (addNamespace) {
            this.startControlledPrefixMapping();
        } else {
            //Remove the namespace, i.e. don´t call startPrefixMapping for parent!
        }

    }

    private void startControlledPrefixMapping() throws SAXException {

        if (this.addNamespace && !this.addedNamespace) {
            //We should add namespace since it is set and has not yet been done.
            super.startPrefixMapping("", this.usedNamespaceUri);

            //Make sure we dont do it twice
            this.addedNamespace = true;
        }
    }

}

这个过滤器被设计成在命名空间不存在时都能够添加它:

new NamespaceFilter("http://www.example.com/namespaceurl", true);

并删除任何现有的命名空间:

new NamespaceFilter(null, false);

在解析时可以使用过滤器如下:

//Prepare JAXB objects
JAXBContext jc = JAXBContext.newInstance("jaxb.package");
Unmarshaller u = jc.createUnmarshaller();

//Create an XMLReader to use with our filter
XMLReader reader = XMLReaderFactory.createXMLReader();

//Create the filter (to add namespace) and set the xmlReader as its parent.
NamespaceFilter inFilter = new NamespaceFilter("http://www.example.com/namespaceurl", true);
inFilter.setParent(reader);

//Prepare the input, in this case a java.io.File (output)
InputSource is = new InputSource(new FileInputStream(output));

//Create a SAXSource specifying the filter
SAXSource source = new SAXSource(inFilter, is);

//Do unmarshalling
Object myJaxbObject = u.unmarshal(source);

要使用此过滤器从 JAXB 对象输出 XML,请查看以下代码。

//Prepare JAXB objects
JAXBContext jc = JAXBContext.newInstance("jaxb.package");
Marshaller m = jc.createMarshaller();

//Define an output file
File output = new File("test.xml");

//Create a filter that will remove the xmlns attribute      
NamespaceFilter outFilter = new NamespaceFilter(null, false);

//Do some formatting, this is obviously optional and may effect performance
OutputFormat format = new OutputFormat();
format.setIndent(true);
format.setNewlines(true);

//Create a new org.dom4j.io.XMLWriter that will serve as the 
//ContentHandler for our filter.
XMLWriter writer = new XMLWriter(new FileOutputStream(output), format);

//Attach the writer to the filter       
outFilter.setContentHandler(writer);

//Tell JAXB to marshall to the filter which in turn will call the writer
m.marshal(myJaxbObject, outFilter);

这有望帮助某人,因为我花了一天时间做这件事,几乎放弃了两次;)

关于java - JAXB:如何在解码 XML 文档期间忽略命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/277502/

相关文章:

java - 如何让Java.xml.Transformer 输出一个没有无用空格和换行符的xml?

c# - 配置的 XML 序列化的替代方案

java - 是否有一个通用的数据结构来表示 Java 中的列表映射

java - 将来自不同 Activity 的值添加到 ArrayList

java - 返回空数组

java - 从 XML 流读取命名空间的最佳方法(使用 Java)

xml - 如何在 Android 的 TableLayout 中设置表格宽度和列数

c# - Xmlserializer 不序列化基类成员

java - 如何编写XStream转换器,通过转换为中间对象进行读写?

java - Struts Web 应用程序中未生成 Log4j 文件?