Java 将org.dom4j.Document转换为org.w3c.dom.Document和XML签名时出现问题

Java 将org.dom4j.Document转换为org.w3c.dom.Document和XML签名时出现问题,java,xml,dom,dom4j,xml-signature,Java,Xml,Dom,Dom4j,Xml Signature,我有一些类已经用来读取XML文件并提供 获取数据的getter方法。现在,我需要添加检查XML数字的可能性 签名 使用org.w3c.dom和以下内容 一切正常 因此,我尝试使用DOMWriter将org.dom4j.Document转换为 org.w3c.dom.Document,但在此之后,签名验证不起作用。我想是的 发生这种情况是因为DOMWiter正在更改XML树(如doc4.asXML()所示) 为了保证文档的完整性,我尝试设置一些内容,但是 DOMWriter没有这样的方法 下面是演

我有一些类已经用来读取XML文件并提供 获取数据的getter方法。现在,我需要添加检查XML数字的可能性 签名

使用org.w3c.dom和以下内容 一切正常

因此,我尝试使用DOMWriter将org.dom4j.Document转换为 org.w3c.dom.Document,但在此之后,签名验证不起作用。我想是的 发生这种情况是因为DOMWiter正在更改XML树(如doc4.asXML()所示)

为了保证文档的完整性,我尝试设置一些内容,但是 DOMWriter没有这样的方法

下面是演示不对称转换的代码

用于测试的文件是

有人知道这样做的原因/解决方法吗

谢谢(对不起,我的英语很差)

例如,如果原始XML以以下开头:

<nfeProc versao="1.10" xmlns="http://www.portalfiscal.inf.br/nfe">
<NFe xmlns="http://www.portalfiscal.inf.br/nfe">
<infNFe Id="NFe31090807301671000131550010001000216008030809" versao="1.10" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...

...
doc4.asXML()返回以下内容:

<nfeProc xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.10">
<NFe>
<infNFe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Id="NFe31090807301671000131550010001000216008030809" versao="1.10">
...

...

我仔细研究了一下,发现dom4jdomwriter做了一些奇怪的w.r.t.名称空间,显然混淆了规范化过程。我没有指出确切的原因,但我认为这与DOMWriter在DOM元素中插入额外的xmlns属性有关。如果打开XML数字签名API的日志记录(如本文所述),则可以看到效果,规范化元素在DOM4J生成的DOM文档中缺少名称空间声明

但是,您可以使用DOM4J DocumentSource和DOMResult通过转换生成DOM文档,而不是使用DOMWriter

/**
 * Create a DOM document from a DOM4J document 
 */
static Document copy(org.dom4j.Document orig) {
    try {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer();
        DOMResult result = new DOMResult();
        t.transform(new DocumentSource(orig), result);
        return (Document) result.getNode();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

使用生成的DOM文档,验证工作正常。

+1对于编写良好的问题,请回答好问题。DOMWriter的输出如何更改XML树?有什么不同?dom4jdomwriter消除了多余的名称空间声明,但这不应该影响XML规范化(因为这种消除是C14n的一部分)。您可以通过删除源文档中的声明来测试这一点。DOM签名验证仍然正确。还有别的事情发生了,很有效,谢谢!我(稍微)看了一下dom4j源代码(上一个稳定版本,1.6.1),但不知道发生了什么。它对我不起作用。我只能依赖W3C解析器,但我正在寻找解决方案。
/**
 * Create a DOM document from a DOM4J document 
 */
static Document copy(org.dom4j.Document orig) {
    try {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer();
        DOMResult result = new DOMResult();
        t.transform(new DocumentSource(orig), result);
        return (Document) result.getNode();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}