我有一个这样的XML文档:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:sec="http://namespace1" xmlns:ser="http://namespace2">
<soap:Header>
<sec:RequestHeader>
<sec:SenderId>ABCD</sec:SenderId>
<sec:SignerId1>ABCD</sec:SignerId1>
<sec:SignerId2></sec:SignerId2>
<sec:SignerId3></sec:SignerId3>
<sec:DBCryptId></sec:DBCryptId>
<sec:RequestId>CPMDDEV4110066</sec:RequestId>
<sec:Timestamp>2015-03-24T15:40:00Z</sec:Timestamp>
<sec:Language>DA</sec:Language>
</sec:RequestHeader>
</soap:Header>
<soap:Body>
<ser:GetStatus>
<ser:dacGetStatusInput>
<ser:MerchantId>A</ser:MerchantId>
<ser:OrderId>B</ser:OrderId>
<ser:CustomerId></ser:CustomerId>
<ser:ActionCode>C</ser:ActionCode>
<ser:Test>Y</ser:Test>
</ser:dacGetStatusInput>
</ser:GetStatus>
</soap:Body>
</soap:Envelope>
无论我做什么,我都不能让org.w3c.dom或JDom在我解析它时停止规范化源文档中的命名空间。
如果我尝试将顶部节点元素添加到新文档中,例如:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document doc = builder.newDocument();
document = doc.importNode(document, true);
doc.appendChild(document);
我发现如果我转储 doc 的内容,则内容已更改为:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<sec:RequestHeader xmlns:sec="http://namespace1">
<sec:SenderId>ABCD</sec:SenderId>
<sec:SignerId1>ABCD</sec:SignerId1>
<sec:SignerId2/>
<sec:SignerId3/>
<sec:DBCryptId/>
<sec:RequestId>CPMDDEV4110066</sec:RequestId>
<sec:Timestamp>2015-03-24T15:40:00Z</sec:Timestamp>
<sec:Language>DA</sec:Language>
</sec:RequestHeader>
</soap:Header>
<soap:Body>
<ser:GetStatus xmlns:ser="http://namespace2">
<ser:dacGetStatusInput>
<ser:MerchantId>A</ser:MerchantId>
<ser:OrderId>B</ser:OrderId>
<ser:CustomerId/>
<ser:ActionCode>C</ser:ActionCode>
<ser:Test>Y</ser:Test>
</ser:dacGetStatusInput>
</ser:GetStatus>
</soap:Body>
</soap:Envelope>
两个名称空间声明 sec 和 ser 已被移动到第一次使用它们的位置。 虽然这种规范化是正确的,但我希望DOM和JDOM停止这样做,并保留我的文档: - )
有关如何实现这一目标的任何建议吗?
答案 0 :(得分:0)
我不确定我是否相信你,至少在谈到JDOM时。如果我运行以下代码:
public static void main(String[] args) throws JDOMException, IOException {
Document doc = new SAXBuilder().build("soap.xml");
XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
xout.output(doc, System.out);
}
将您的文档作为&#34; soap.xml&#34;,我得到输出:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:sec="http://namespace1" xmlns:ser="http://namespace2">
<soap:Header>
<sec:RequestHeader>
<sec:SenderId>ABCD</sec:SenderId>
<sec:SignerId1>ABCD</sec:SignerId1>
<sec:SignerId2 />
<sec:SignerId3 />
<sec:DBCryptId />
<sec:RequestId>CPMDDEV4110066</sec:RequestId>
<sec:Timestamp>2015-03-24T15:40:00Z</sec:Timestamp>
<sec:Language>DA</sec:Language>
</sec:RequestHeader>
</soap:Header>
<soap:Body>
<ser:GetStatus>
<ser:dacGetStatusInput>
<ser:MerchantId>A</ser:MerchantId>
<ser:OrderId>B</ser:OrderId>
<ser:CustomerId />
<ser:ActionCode>C</ser:ActionCode>
<ser:Test>Y</ser:Test>
</ser:dacGetStatusInput>
</ser:GetStatus>
</soap:Body>
</soap:Envelope>
这就是我所期望的。
JDOM尊重声明它们的元素的xmlns
声明,但是,如果你&#34;移动&#34;将元素放入未继承命名空间的位置,它将在需要的位置声明它。让我解释一下......
Document doc = new SAXBuilder().build("soap.xml");
XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
xout.output(doc, System.out);
上面的代码只是简单地读取并转储整个文档,但是,如果我们这样做(阅读文档,提取子集,将子集添加到新文档并打印):
Document doc = new SAXBuilder().build("soap.xml");
XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
//xout.output(doc, System.out);
Namespace soap = Namespace.getNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");
Namespace sec = Namespace.getNamespace("sec", "http://namespace1");
// locate, and extract rhead
Element rhead = doc.getRootElement().getChild("Header", soap).getChild("RequestHeader", sec);
rhead.detach();
// add it to a new Soap doc.
Element nroot = new Element("Dummy", soap);
nroot.addContent(rhead);
Document ndoc = new Document(nroot);
// Print the new document
xout.output(ndoc, System.out);
//Now force-declare the namespace on the root element:
nroot.addNamespaceDeclaration(sec);
System.out.println("\nForced\n");
xout.output(ndoc, System.out);
以上将输出虚拟文档两次,一次使用命名空间的as-need声明,第二次将声明添加到根元素:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Dummy xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<sec:RequestHeader xmlns:sec="http://namespace1">
<sec:SenderId>ABCD</sec:SenderId>
<sec:SignerId1>ABCD</sec:SignerId1>
<sec:SignerId2 />
<sec:SignerId3 />
<sec:DBCryptId />
<sec:RequestId>CPMDDEV4110066</sec:RequestId>
<sec:Timestamp>2015-03-24T15:40:00Z</sec:Timestamp>
<sec:Language>DA</sec:Language>
</sec:RequestHeader>
</soap:Dummy>
Forced
<?xml version="1.0" encoding="UTF-8"?>
<soap:Dummy xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:sec="http://namespace1">
<sec:RequestHeader>
<sec:SenderId>ABCD</sec:SenderId>
<sec:SignerId1>ABCD</sec:SignerId1>
<sec:SignerId2 />
<sec:SignerId3 />
<sec:DBCryptId />
<sec:RequestId>CPMDDEV4110066</sec:RequestId>
<sec:Timestamp>2015-03-24T15:40:00Z</sec:Timestamp>
<sec:Language>DA</sec:Language>
</sec:RequestHeader>
</soap:Dummy>
JDOM非常有能力做你想做的事。