private void RemoveDuplicateNamespace(XmlElement elem, XmlNamespaceManager mgr, bool fCheckElemAttrs)
{
//remove the duplicate attributes on current node first
mgr.PushScope();
XmlAttributeCollection attrs = elem.Attributes;
int cAttrs = attrs.Count;
if (fCheckElemAttrs && cAttrs > 0)
{
for (int i = cAttrs - 1; i >= 0; --i)
{
XmlAttribute attr = attrs[i];
if (attr.Prefix == _doc.strXmlns)
{
string nsUri = mgr.LookupNamespace(attr.LocalName);
if (nsUri != null)
{
if (attr.Value == nsUri)
elem.Attributes.RemoveNodeAt(i);
}
else
{
// Add this namespace, so it we will behave correctly when setting "<bar xmlns:p="BAR"><foo2 xmlns:p="FOO"/></bar>" as
// InnerXml on this foo elem where foo is like this "<foo xmlns:p="FOO"></foo>"
// If do not do this, then we will remove the inner p prefix definition and will let the 1st p to be in scope for
// the subsequent InnerXml_set or setting an EntRef inside.
mgr.AddNamespace(attr.LocalName, attr.Value);
}
}
else if (attr.Prefix.Length == 0 && attr.LocalName == _doc.strXmlns)
{
string nsUri = mgr.DefaultNamespace;
if (nsUri != null)
{
if (attr.Value == nsUri)
elem.Attributes.RemoveNodeAt(i);
}
else
{
// Add this namespace, so it we will behave correctly when setting "<bar xmlns:p="BAR"><foo2 xmlns:p="FOO"/></bar>" as
// InnerXml on this foo elem where foo is like this "<foo xmlns:p="FOO"></foo>"
// If do not do this, then we will remove the inner p prefix definition and will let the 1st p to be in scope for
// the subsequent InnerXml_set or setting an EntRef inside.
mgr.AddNamespace(attr.LocalName, attr.Value);
}
}
}
}
//now recursively remove the duplicate attributes on the children
XmlNode child = elem.FirstChild;
while (child != null)
{
XmlElement childElem = child as XmlElement;
if (childElem != null)
RemoveDuplicateNamespace(childElem, mgr, true);
child = child.NextSibling;
}
mgr.PopScope();
}