同样的问题在这里。似乎是由于演变而在JVM内部的一个错误。
我把它拖到com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment
在java 7u21及更早版本中:
91: // Element selectedElem = doc.getElementById(id);
92: selectedElem = IdResolver.getElementById(doc, id);
在 java 7u25 中:
87: selectedElem = doc.getElementById(id);
//...
93: if (secureValidation) {
secureValidation
引用java 7u25在XML Sig验证上的进化(参见changelog),所以他们在进行这种演变时一定已经破坏了其他东西。
我们通过提供一个自定义来解决此问题,该自定义能够解析尚未在 DOM 文档树中的节点(XMLObject 中的片段)。javax.xml.crypto.URIDereferencer
javax.xml.crypto.dom.DOMCryptoContext.setURIDereferencer(URIDereferencer)
我现在向Oracle报告此事,我将使用错误ID更新答案。
编辑:在apache SVN中找到这个
编辑 2 :多亏了这个错误报告,我明白这是XML“Id”属性处理的演变。
以前版本的java / JSR-105 / SANTUARIO曾经对中使用的“Id”属性非常宽容,但是这个新版本需要一个标识为ID XML说话的属性。我的意思是,命名属性“Id”或“ID”已经不够了,你需要通过XSD / DTD架构验证将其标记为ID。document.getElementById(...)
不幸的是,我正在遵循一个无效的模式,因此Java无法解析。
如果您处于相同的情况,请参阅下面的解决方案。否则,如果 XML 文档具有有效的架构,请查看@sherb解决方案 https://stackoverflow.com/a/17437919/233906
溶液
幸运的是,您可以使用Element.setIdAttributeNode(org.w3c.dom.Attr,boolean)
等方法将属性标记为ID。
结合一点XPath,比如获取“Id”节点加上一点Java,应该会让你摆脱麻烦。descendant-or-self::*/@Id
Attr
((Element)attr.getOwnerElement()).setIdAttributeNode(attr,true)
但要小心:仅对当前文档和节点有效。如果你 // 你需要在每个 DOM 树的新节点上做一个setIdAttributeXXX()
clone
adopt
import
setIdAttributeXXX()