我通过 SignedXml 和 Reference 类对 XPointer 操作进行了逆向工程,并且..我可以在单独的答案中为您提供所有详细信息,但我现在的结论是,您只能有两种类型的查询:
#xpointer(/)
这是有效的,因为它被明确检查,并且
#xpointer(id(
再次明确(使用 string.StartsWith)检查。
因此,正如您在评论中指出的那样,实现此目的的唯一方法似乎是扩展 SignedXml 类并重写 GetIdElement 方法,如下所示:
public class CustomSignedXml : SignedXml
{
XmlDocument xmlDocumentToSign;
public CustomSignedXml(XmlDocument xmlDocument) : base(xmlDocument)
{
xmlDocumentToSign = xmlDocument;
}
public override XmlElement GetIdElement(XmlDocument document, string idValue)
{
XmlElement matchingElement = null;
try
{
matchingElement = base.GetIdElement(document, idValue);
}
catch (Exception idElementException)
{
Trace.TraceError(idElementException.ToString());
}
if (matchingElement == null)
{
// at this point, idValue = xpointer(//*[@authenticate='true'])
string customXPath = idValue.TrimEnd(')');
customXPath = customXPath.Substring(customXPath.IndexOf('(') + 1);
matchingElement = xmlDocumentToSign.SelectSingleNode(customXPath) as XmlElement;
}
return matchingElement;
}
}
然后在消费者代码中,只需将SignedXml更改为CustomSignedXml即可:
CustomSignedXml signedXml = new CustomSignedXml(xmlDoc);