使用 java 在 xml 元素中包含重复的命名空间
Include repetitive namespaces in xml elements using java
我有一个不寻常的请求。我需要生成一个 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 的一种方式,在您需要的元素上显式创建名称空间声明并使用 LSSerializer 写出树。
我有一个不寻常的请求。我需要生成一个 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 的一种方式,在您需要的元素上显式创建名称空间声明并使用 LSSerializer 写出树。