我有一个不寻常的请求。我需要生成一个 xml 文件来查找如下内容
<?xml version="1.0" encoding="UTF-8"?>
<pk:DeviceInfo xmlns:pk="urn:ietf:params:xml:ns:kyp:pk" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<pk:Manufacturer xmlns:pk="urn:ietf:params:xml:ns:kyp:pk" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
ABC
</pk:Manufacturer>
<pk:SerialNo>123456</pk:SerialNo>
<pk:Model>Model1</pk:Model>
<pk:IssueNo>1</pk:IssueNo>
</pk:DeviceInfo>
我正在使用 jdom api 生成 xml。问题是,即使我为 pk:Manufacturer 元素声明命名空间,jdom 也不会将其添加到那里,因为它已经在根元素中声明了。但我还需要在子元素中重复命名空间声明,因为我需要将此文件发送到另一个需要 xml 采用这种格式的服务器。
我相信 jdom 不允许这样做,所以我尝试首先使用 jdom 创建 xml,并使用 dom 解析器更新 xml,以使用 elmt.setAttributeNS() 将命名空间包含到子元素中,但不幸的是,这似乎不起作用。
有人遇到过这个问题吗?
最佳答案
您没有向我们展示您尝试过哪些 DOM 代码,但当我测试时
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
String ns1 = "http://example.com/ns1";
String ns2 = "http://example.com/ns2";
Element root = doc.createElementNS(ns1, "pf1:root");
root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:pf2", ns2);
doc.appendChild(root);
Element foo = doc.createElementNS(ns1, "pf1:foo");
foo.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:pf1", ns1);
foo.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:pf2", ns2);
root.appendChild(foo);
DOMImplementationLS domImp = (DOMImplementationLS)doc.getImplementation();
LSSerializer ser = domImp.createLSSerializer();
System.out.println(ser.writeToString(doc));
使用 Oracle Java 1.8 时,输出为
<pf1:root xmlns:pf1="http://example.com/ns1" xmlns:pf2="http://example.com/ns2"><pf1:foo xmlns:pf1="http://example.com/ns1" xmlns:pf2="http://example.com/ns2"/></pf1:root>
因此,子级上显式创建的命名空间属性声明被序列化。因此,这应该是 W3C DOM 的一种方式,在您需要的元素上显式创建 namespace 声明,并使用 LSSerializer 写出树。
关于java - 使用 java 在 xml 元素中包含重复的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40628212/