|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections;
using System.Xml;
namespace System.Security.Cryptography.Xml
{
// the stack of currently active NamespaceFrame contexts. this
// object also maintains the inclusive prefix list in a tokenized form.
internal sealed class ExcAncestralNamespaceContextManager : AncestralNamespaceContextManager
{
private readonly Hashtable _inclusivePrefixSet;
internal ExcAncestralNamespaceContextManager(string inclusiveNamespacesPrefixList)
{
_inclusivePrefixSet = Utils.TokenizePrefixListString(inclusiveNamespacesPrefixList);
}
private bool HasNonRedundantInclusivePrefix(XmlAttribute attr)
{
string nsPrefix = Utils.GetNamespacePrefix(attr);
return _inclusivePrefixSet.ContainsKey(nsPrefix) &&
Utils.IsNonRedundantNamespaceDecl(attr, GetNearestRenderedNamespaceWithMatchingPrefix(nsPrefix, out _));
}
private void GatherNamespaceToRender(string nsPrefix, SortedList nsListToRender, Hashtable nsLocallyDeclared)
{
foreach (object a in nsListToRender.GetKeyList())
{
if (Utils.HasNamespacePrefix((XmlAttribute)a, nsPrefix))
return;
}
int rDepth;
XmlAttribute? local = (XmlAttribute?)nsLocallyDeclared[nsPrefix];
XmlAttribute? rAncestral = GetNearestRenderedNamespaceWithMatchingPrefix(nsPrefix, out rDepth);
if (local != null)
{
if (Utils.IsNonRedundantNamespaceDecl(local, rAncestral))
{
nsLocallyDeclared.Remove(nsPrefix);
nsListToRender.Add(local, null);
}
}
else
{
int uDepth;
XmlAttribute? uAncestral = GetNearestUnrenderedNamespaceWithMatchingPrefix(nsPrefix, out uDepth);
if (uAncestral != null && uDepth > rDepth && Utils.IsNonRedundantNamespaceDecl(uAncestral, rAncestral))
{
nsListToRender.Add(uAncestral, null);
}
}
}
internal override void GetNamespacesToRender(XmlElement element, SortedList attrListToRender, SortedList nsListToRender, Hashtable nsLocallyDeclared)
{
GatherNamespaceToRender(element.Prefix, nsListToRender, nsLocallyDeclared);
foreach (object attr in attrListToRender.GetKeyList())
{
string prefix = ((XmlAttribute)attr).Prefix;
if (prefix.Length > 0)
GatherNamespaceToRender(prefix, nsListToRender, nsLocallyDeclared);
}
}
internal override void TrackNamespaceNode(XmlAttribute attr, SortedList nsListToRender, Hashtable nsLocallyDeclared)
{
if (HasNonRedundantInclusivePrefix(attr))
nsListToRender.Add(attr, null);
else
nsLocallyDeclared.Add(Utils.GetNamespacePrefix(attr), attr);
}
internal override void TrackXmlNamespaceNode(XmlAttribute attr, SortedList nsListToRender, SortedList attrListToRender, Hashtable nsLocallyDeclared)
{
// exclusive canonicalization treats Xml namespaces as simple attributes. They are not propagated.
attrListToRender.Add(attr, null);
}
}
}
|