更新
这不适用于两个文档具有冲突的命名空间前缀的情况(来自第二个文档的映射将替换来自第一个文档的映射)。
您可以将命名空间声明从第二个文档复制到导入的节点。由于子节点可以覆盖父节点前缀,因此这是有效的:
<foo:root xmlns:foo="urn:ROOT">
<foo:child xmlns:foo="urn:CHILD" xsi:type="foo:child-type">
...
</foo:child>
</foo:root>
在上面的 XML 中,绑定到前缀“foo”的命名空间在子元素的范围内被覆盖。您可以通过执行以下操作为您的用例完成此操作:
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Demo {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
File file1 = new File("src/forum231/input1.xml");
Document doc1 = db.parse(file1);
Element rootElement1 = doc1.getDocumentElement();
File file2 = new File("src/forum231/input2.xml");
Document doc2 = db.parse(file2);
Element rootElement2 = doc2.getDocumentElement();
// Copy Child Nodes
NodeList childNodes2 = rootElement2.getChildNodes();
for(int x=0; x<childNodes2.getLength(); x++) {
Node importedNode = doc1.importNode(childNodes2.item(x), true);
if(importedNode.getNodeType() == Node.ELEMENT_NODE) {
Element importedElement = (Element) importedNode;
// Copy Attributes
NamedNodeMap namedNodeMap2 = rootElement2.getAttributes();
for(int y=0; y<namedNodeMap2.getLength(); y++) {
Attr importedAttr = (Attr) doc1.importNode(namedNodeMap2.item(y), true);
importedElement.setAttributeNodeNS(importedAttr);
}
}
rootElement1.appendChild(importedNode);
}
// Output Document
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
DOMSource source = new DOMSource(doc1);
StreamResult result = new StreamResult(System.out);
t.transform(source, result);
}
}
输出
<?xml version="1.0" encoding="UTF-8" standalone="no"?><tt:root xmlns:tt="http://myurl.com/">
<tt:child/>
<tt:child/>
<ns1:child xmlns:ns1="http://myurl.com/" xmlns:ns2="http://myotherurl.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<ns1:child xmlns:ns1="http://myurl.com/" xmlns:ns2="http://myotherurl.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:SomeType"/>
</tt:root>
原始答案
除了复制元素之外,您还可以复制属性。这将确保生成的文档包含必要的命名空间声明:
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Demo {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
File file1 = new File("input1.xml");
Document doc1 = db.parse(file1);
Element rootElement1 = doc1.getDocumentElement();
File file2 = new File("input2.xml");
Document doc2 = db.parse(file2);
Element rootElement2 = doc2.getDocumentElement();
// Copy Attributes
NamedNodeMap namedNodeMap2 = rootElement2.getAttributes();
for(int x=0; x<namedNodeMap2.getLength(); x++) {
Attr importedNode = (Attr) doc1.importNode(namedNodeMap2.item(x), true);
rootElement1.setAttributeNodeNS(importedNode);
}
// Copy Child Nodes
NodeList childNodes2 = rootElement2.getChildNodes();
for(int x=0; x<childNodes2.getLength(); x++) {
Node importedNode = doc1.importNode(childNodes2.item(x), true);
rootElement1.appendChild(importedNode);
}
// Output Document
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
DOMSource source = new DOMSource(doc1);
StreamResult result = new StreamResult(System.out);
t.transform(source, result);
}
}
输出:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<tt:root xmlns:tt="http://myurl.com/" xmlns:ns1="http://myurl.com/" xmlns:ns2="http://myotherurl.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tt:child/>
<tt:child/>
<ns1:child/>
<ns1:child xsi:type="ns2:SomeType"/>
</tt:root>