I finally found the solution. I want to write it in case someone else needs it. When canonicalizing a sub node, you have to add parent nodes namespaces. It does not matter if you use it in the related sub node or not. Therefore, before canonicalizing the element, I added the namespaces belong to parent nodes to my XmlElement.
public static string Canonicalize(XmlElement Element)
{
//Create [NamespaceList]
#region
var NamespaceList = new Dictionary<string, string>();
ModifyNamespaceList(Element, ref NamespaceList);
#endregion
foreach (var Namespace in NamespaceList)
{
Element.SetAttribute(Namespace.Key, Namespace.Value);
}
var ElementStream = new MemoryStream();
var ElementWrtier = XmlWriter.Create(ElementStream);
Element.WriteTo(ElementWrtier);
ElementWrtier.Flush();
ElementStream.Position = 0;
var c14n = new XmlDsigC14NTransform(false);
c14n.LoadInput(ElementStream);
using (var OutStream = (Stream)c14n.GetOutput(typeof(Stream)))
using (var OutStreamReader = new StreamReader(OutStream, Encoding.UTF8))
{
return OutStreamReader.ReadToEnd();
}
}
private static void ModifyNamespaceList(XmlNode Node, ref Dictionary<string, string> NamespaceList)
{
if (Node.Attributes != null)
{
foreach (XmlAttribute item in Node.Attributes)
{
if (item.Prefix == "xmlns" || item.Name == "xmlns")
{
if (!NamespaceList.TryGetValue(item.Name, out string Value))
{
NamespaceList.Add(item.Name, item.Value);
}
}
}
}
if (Node.ParentNode != null)
{
ModifyNamespaceList(Node.ParentNode, ref NamespaceList);
}
}