我想通過使用System.Security.Cryptography.Xml.XMLDsigC14nTransform
類的c#.net Framework 2.0來規範化一個xml節點。如何在C#中使用XmlDsigC14NTransform類
實例需要三種不同的輸入類型: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());
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>
Child1.xml
<Child1 xmlns:test="http://www.test.com/xades#"></Child1>
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>
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>
ms2.xml
<Child1 Attribute1="c1" Bttribute="c2" Cttribute="c3">
<child11 Attribute11="c11">Element11</child11>
</Child1>
該輸出似乎是正確的。非常感謝您的寶貴時間。 – artsince 2010-08-08 14:24:31
我比較結果與我寫的一些java代碼。用java我不會在行尾看到「 」。哪一個是正確的實施? – artsince 2010-08-09 09:40:32
如果信息源在達到上述處理時已獲得元素內容中的U + 000D個字符,則 表單是正確的,如果沒有,則另一個表單是正確的。這種差異可能不在規範化,而是在基礎流讀取或文檔加載中。我懷疑其中一個或其他實現是「修復」換行符。無論哪種做法都是有缺陷的,不過就你如何獲取XML和/或節點而言,不是c14n。 – 2010-08-09 12:38:22