我在生成带有签名节点的文档时遇到问题。我有一堆文本格式的签名XML。它们的签名是有效的,我已经用xmlsec1对它进行了测试。我必须加载所有XML并将它们放在另一个XML文档中,以便将其发送到另一个服务。 所以,首先我创建容器文档(" sobre"是一个局部变量,一个JAXB根元素):
JAXBContext context = JAXBContext.newInstance("org.importe.test");
StringWriter writer = new StringWriter();
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(sobre, writer);
String xml = writer.toString();
Document doc = loadXMLFromString(xml);
然后我将XML添加到容器中:
for (String cfexml : cfexmls) {
Document cfe = loadXMLFromString(cfexml);
Node newNode = doc.importNode(cfe.getDocumentElement(), true);
doc.getElementsByTagName("EnvioCFE").item(0).appendChild(newNode);
}
最后我从容器文档中获取了xml:
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
StringWriter outputWriter = new StringWriter();
trans.transform(new DOMSource(doc), new StreamResult(outputWriter));
String signedxml = outputWriter.toString();
重点是我修改了子节点,没有名称空间,因此提取节点的签名验证失败。以下是我作为子节点添加的XML的摘录:
<?xml version="1.0" encoding="UTF-8"?>
<CFE xmlns="http://org.importe.test" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns:ns3="http://www.w3.org/2001/04/xmlenc#" version="1.0">
<data>
[...]
</data>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
[...]
</Signature>
</CFE>
但是当容器文档中导入节点时,它会被修改(实际上我已经注意到它没有松散的命名空间声明):
<?xml version="1.0" encoding="UTF-8"?>
<EnvioCFE xmlns="http://org.importe.test" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns:ns3="http://www.w3.org/2001/04/xmlenc#" version="1.0">
<Header version="1.0">
</Header>
<CFE version="1.0">
<data>
[...]
</data>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
[...]
</Signature>
</CFE>
</EnvioCFE>
如何在保留命名空间声明的容器中添加节点?更一般地说,我可以添加它确保它已添加&#34;原样是#34;,没有任何修改? (我使用glassfish 4和Java 7)
谢谢
编辑:
这是loadXMLFromString:
的代码public Document loadXMLFromString(String xml) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new InputSource(new StringReader(xml)));
}
答案 0 :(得分:0)
好的,我做过研究,我发现了问题:
我希望这可以帮助某人,无论如何我不知道为什么会发生这种情况,我确信我不是在做奇怪的事情,但我现在没有时间去深入了。
实际上我很难找到告诉glassfish如何加载我想要的DOM实现,或者设置优先级:我发现没办法说“加载xerces而不是标准库”。