art*_*nce 5 c# xml canonicalization xml-signature
我试图通过使用System.Security.Cryptography.Xml.XMLDsigC14nTransform
c#.net Framework 2.0类来规范化xml节点。
该实例需要三种不同的输入类型,即NodeList,Stream和XMLDocument。我尝试使用所有这些输入类型进行转换,但是得到了不同的结果。我真正想做的是规范化单个节点,但是正如您在输出文件中看到的那样,输出不包含任何内部xml。
非常感谢有关规范XML节点的正确方法的任何建议。最好,
string path = @"D:\Test\xml imza\sign.xml";
XmlDocument xDoc = new XmlDocument();
xDoc.PreserveWhitespace = true;
using (FileStream fs = new FileStream(path, FileMode.Open))
{
xDoc.Load(fs);
}
// canon node list
XmlNodeList nodeList = xDoc.SelectNodes("//Child1");
XmlDsigC14NTransform transform = new XmlDsigC14NTransform();
transform.LoadInput(nodeList);
MemoryStream ms = (MemoryStream)transform.GetOutput(typeof(Stream));
File.WriteAllBytes(@"D:\Test\xml imza\child1.xml", ms.ToArray());
// canon XMLDocument
transform = new XmlDsigC14NTransform();
transform.LoadInput(xDoc);
ms = (MemoryStream)transform.GetOutput(typeof(Stream));
File.WriteAllBytes(@"D:\Test\xml imza\doc.xml", ms.ToArray());
// Document to Stream
ms = new MemoryStream();
XmlWriter xw = XmlWriter.Create(ms);
xDoc.WriteTo(xw);
xw.Flush();
ms.Position = 0;
transform = new XmlDsigC14NTransform();
transform.LoadInput(ms);
ms = (MemoryStream)transform.GetOutput(typeof(Stream));
File.WriteAllBytes(@"D:\Test\xml imza\ms.xml", ms.ToArray());
// node to stream
ms = new MemoryStream();
xw = XmlWriter.Create(ms);
nodeList[0].WriteTo(xw);
xw.Flush();
ms.Position = 0;
transform = new XmlDsigC14NTransform();
transform.LoadInput(ms);
ms = (MemoryStream)transform.GetOutput(typeof(Stream));
File.WriteAllBytes(@"D:\Test\xml imza\ms2.xml", ms.ToArray());
Run Code Online (Sandbox Code Playgroud)
sign.xml
<?xml version="1.0" encoding="utf-8" ?>
<Root Attr="root" xmlns:test="http://www.test.com/xades#">
<Child1 Cttribute="c3" Attribute1="c1" Bttribute="c2">
<child11 Attribute11="c11">Element11</child11>
</Child1>
<Child2 Attribute2="c2">
<child21 Attribute21="c21">Element21</child21>
<child22 Attribute22="c22">Element22</child22>
</Child2>
<Child3 Attribute3="c3">
<child31 Attribute32="c31">
<child311 Attribute311="c311">Element311</child311>
</child31>
</Child3>
</Root>
Run Code Online (Sandbox Code Playgroud)
Child1.xml
<Child1 xmlns:test="http://www.test.com/xades#"></Child1>
Run Code Online (Sandbox Code Playgroud)
doc.xml
<Root xmlns:test="http://www.test.com/xades#" Attr="root">
<Child1 Attribute1="c1" Bttribute="c2" Cttribute="c3">
<child11 Attribute11="c11">Element11</child11>
</Child1>
<Child2 Attribute2="c2">
<child21 Attribute21="c21">Element21</child21>
<child22 Attribute22="c22">Element22</child22>
</Child2>
<Child3 Attribute3="c3">
<child31 Attribute32="c31">
<child311 Attribute311="c311">Element311</child311>
</child31>
</Child3> 
</Root>
Run Code Online (Sandbox Code Playgroud)
ms.xml
<Root xmlns:test="http://www.test.com/xades#" Attr="root">
<Child1 Attribute1="c1" Bttribute="c2" Cttribute="c3">
<child11 Attribute11="c11">Element11</child11>
</Child1>
<Child2 Attribute2="c2">
<child21 Attribute21="c21">Element21</child21>
<child22 Attribute22="c22">Element22</child22>
</Child2>
<Child3 Attribute3="c3">
<child31 Attribute32="c31">
<child311 Attribute311="c311">Element311</child311>
</child31>
</Child3>
</Root>
Run Code Online (Sandbox Code Playgroud)
ms2.xml
<Child1 Attribute1="c1" Bttribute="c2" Cttribute="c3">
<child11 Attribute11="c11">Element11</child11>
</Child1>
Run Code Online (Sandbox Code Playgroud)
我想,你的答案就在你的问题中,“我真正想做的是规范化单个节点,但正如你在输出文件中看到的那样,输出不包含任何内部 xml。”
如果我理解您的意思,那么您确实不想规范化单个节点,或者您会很高兴它不包含内部 XML。您想要规范化单个子树。
XPath 返回节点,而不是子树。默认情况下,XPath 表达式返回的节点上的某些操作将包括其子节点和属性节点,但规范化故意不是其中之一,因为其中一些子节点可能会以您未签名的方式可变。在签名时,您仅对您所说的正在签名的节点进行签名。
将代码中的行更改为:
XmlNodeList nodeList = xDoc.SelectNodes("//Child1");
Run Code Online (Sandbox Code Playgroud)
到:
XmlNodeList nodeList =
xDoc.SelectNodes("//Child1/descendant-or-self::node()|//Child1//@*");
Run Code Online (Sandbox Code Playgroud)
意味着我在 child1.xml 中得到以下内容:
<Child1 xmlns:test="http://www.test.com/xades#" Attribute1="c1" Bttribute="c2" Cttribute="c3">
<child11 Attribute11="c11">Element11</child11>
</Child1>
Run Code Online (Sandbox Code Playgroud)
我认为这就是你想要的是否正确?
顺便说一句,更精确的是:
XmlNodeList nodeList =
xDoc.SelectNodes("//Child1[1]/descendant-or-self::node()|//Child1[1]//@*");
Run Code Online (Sandbox Code Playgroud)
可能有用,因为 xpath 评估可以在到达第一个时停止</Child1>
,如果您的实际数据很大,则性能增益可能会很大。
归档时间: |
|
查看次数: |
6847 次 |
最近记录: |