用Java编写XML命名空间

时间:2017-07-30 11:42:20

标签: java xml xml-namespaces

我已经看到了一些较旧的答案,但我找不到针对这种特殊情况的解决方案。

我正在寻找下一个输出:

<?xml version="1.0" encoding="UTF-8"?>
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">
 <manifest:file-entry manifest:full-path="/" manifest:version="1.2" manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/>
</manifest:manifest>

所以,我尝试了下一个代码:

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {
    public static void main(String args[]){
        final String MIMETYPE =  "application/vnd.oasis.opendocument.spreadsheet";
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document dom = db.newDocument();
            Element e = null;

            Element rootEle = dom.createElementNS("manifest","manifest");
            rootEle.setAttributeNS("manifest","version","1.2");
            rootEle.setAttributeNS("xmlns","manifest","urn:oasis:names:tc:opendocument:xmlns:manifest:1.0");

            e = dom.createElementNS("manifest","file-entry");
            e.setAttributeNS("manifest","full-path","/");
            e.setAttributeNS("manifest","version","1.2");
            e.setAttributeNS("manifest","media-type",MIMETYPE);
            rootEle.appendChild(e);

            dom.appendChild(rootEle);

            try {
                Transformer tr = TransformerFactory.newInstance().newTransformer();
                tr.setOutputProperty(OutputKeys.INDENT, "yes");
                tr.setOutputProperty(OutputKeys.METHOD, "xml");
                tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
                tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

                FileOutputStream o = new FileOutputStream("Output.xml");
                tr.transform(new DOMSource(dom),
                        new StreamResult(o));

                o.close();
            } catch (TransformerException te) {
                System.err.println(te.getMessage());
            } catch (IOException ioe) {
                System.err.println(ioe.getMessage());
            }
        } catch (ParserConfigurationException pce) {
            System.err.println("UsersXML: Error trying to instantiate DocumentBuilder " + pce);
        }
    }
}

我得到下一个输出:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<manifest xmlns:ns0="xmlns" ns0:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" xmlns:ns1="manifest" ns1:version="1.2" xmlns="manifest">
    <file-entry xmlns:ns0="manifest" ns0:full-path="/" ns1:media-type="application/vnd.oasis.opendocument.spreadsheet" xmlns:ns2="manifest" ns2:version="1.2"/>
</manifest>

这会破坏命名空间!我怎样才能得到正确的输出?

1 个答案:

答案 0 :(得分:1)

set*NS(...)方法的第一个参数必须是名称空间URI,而不是前缀。在你的情况下,它是“urn:oasis:names:tc:opendocument:xmlns:manifest:1.0”。但是,您可以(并且必须)在name参数中指定前缀。以下源代码将生成所需的输出:

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {
    public static void main(String args[]){
        final String MIMETYPE = "application/vnd.oasis.opendocument.spreadsheet";
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document dom = db.newDocument();
            Element e = null;

            String namespace = "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0";

            Element rootEle = dom.createElementNS(namespace, "manifest:manifest");
            rootEle.setAttributeNS(namespace, "manifest:version","1.2");

            e = dom.createElementNS(namespace, "manifest:file-entry");
            e.setAttributeNS(namespace, "manifest:full-path","/");
            e.setAttributeNS(namespace, "manifest:version","1.2");
            e.setAttributeNS(namespace, "manifest:media-type",MIMETYPE);
            rootEle.appendChild(e);

            dom.appendChild(rootEle);

            try {
                Transformer tr = TransformerFactory.newInstance().newTransformer();
                tr.setOutputProperty(OutputKeys.INDENT, "yes");
                tr.setOutputProperty(OutputKeys.METHOD, "xml");
                tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
                tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

                FileOutputStream o = new FileOutputStream("Output.xml");
                tr.transform(new DOMSource(dom), new StreamResult(o));

                o.close();
            } catch (TransformerException te) {
                System.err.println(te.getMessage());
            } catch (IOException ioe) {
                System.err.println(ioe.getMessage());
            }
        } catch (ParserConfigurationException pce) {
            System.err.println("UsersXML: Error trying to instantiate DocumentBuilder " + pce);
        }
    }
}