AngleSharp by AngleSharp

<PackageReference Include="AngleSharp" Version="0.9.9.2" />

 NamedNodeMap

NamedNodeNap is a key/value pair of nodes that can be accessed by numeric or string index.
using AngleSharp.Extensions; using System; using System.Collections; using System.Collections.Generic; namespace AngleSharp.Dom.Collections { internal sealed class NamedNodeMap : INamedNodeMap, IEnumerable<IAttr>, IEnumerable { private readonly List<Attr> _items; private readonly WeakReference<Element> _owner; public IAttr this[string name] { get { return GetNamedItem(name); } } public IAttr this[int index] { get { if (index < 0 || index >= _items.Count) return null; return _items[index]; } } public int Length => _items.Count; public NamedNodeMap(Element owner) { _items = new List<Attr>(); _owner = new WeakReference<Element>(owner); } internal void FastAddItem(Attr attr) { _items.Add(attr); } internal void RaiseChangedEvent(Attr attr, string newValue, string oldValue) { Element target = null; if (_owner.TryGetTarget(out target)) target.AttributeChanged(attr.LocalName, attr.NamespaceUri, oldValue, newValue); } internal IAttr RemoveNamedItemOrDefault(string name, bool suppressMutationObservers) { for (int i = 0; i < _items.Count; i++) { if (name.Is(_items[i].Name)) { Attr attr = _items[i]; _items.RemoveAt(i); attr.Container = null; if (!suppressMutationObservers) RaiseChangedEvent(attr, null, attr.Value); return attr; } } return null; } internal IAttr RemoveNamedItemOrDefault(string name) { return RemoveNamedItemOrDefault(name, false); } internal IAttr RemoveNamedItemOrDefault(string namespaceUri, string localName, bool suppressMutationObservers) { for (int i = 0; i < _items.Count; i++) { if (localName.Is(_items[i].LocalName) && namespaceUri.Is(_items[i].NamespaceUri)) { Attr attr = _items[i]; _items.RemoveAt(i); attr.Container = null; if (!suppressMutationObservers) RaiseChangedEvent(attr, null, attr.Value); return attr; } } return null; } internal IAttr RemoveNamedItemOrDefault(string namespaceUri, string localName) { return RemoveNamedItemOrDefault(namespaceUri, localName, false); } public IAttr GetNamedItem(string name) { for (int i = 0; i < _items.Count; i++) { if (name.Is(_items[i].Name)) return _items[i]; } return null; } public IAttr GetNamedItem(string namespaceUri, string localName) { for (int i = 0; i < _items.Count; i++) { if (localName.Is(_items[i].LocalName) && namespaceUri.Is(_items[i].NamespaceUri)) return _items[i]; } return null; } public IAttr SetNamedItem(IAttr item) { Attr attr = Prepare(item); if (attr != null) { string name = item.Name; for (int i = 0; i < _items.Count; i++) { if (name.Is(_items[i].Name)) { Attr attr2 = _items[i]; _items[i] = attr; RaiseChangedEvent(attr, attr.Value, attr2.Value); return attr2; } } _items.Add(attr); RaiseChangedEvent(attr, attr.Value, null); } return null; } public IAttr SetNamedItemWithNamespaceUri(IAttr item, bool suppressMutationObservers) { Attr attr = Prepare(item); if (attr != null) { string localName = item.LocalName; string namespaceUri = item.NamespaceUri; for (int i = 0; i < _items.Count; i++) { if (localName.Is(_items[i].LocalName) && namespaceUri.Is(_items[i].NamespaceUri)) { Attr attr2 = _items[i]; _items[i] = attr; if (!suppressMutationObservers) RaiseChangedEvent(attr, attr.Value, attr2.Value); return attr2; } } _items.Add(attr); if (!suppressMutationObservers) RaiseChangedEvent(attr, attr.Value, null); } return null; } public IAttr SetNamedItemWithNamespaceUri(IAttr item) { return SetNamedItemWithNamespaceUri(item, false); } public IAttr RemoveNamedItem(string name) { IAttr attr = RemoveNamedItemOrDefault(name); if (attr == null) throw new DomException(DomError.NotFound); return attr; } public IAttr RemoveNamedItem(string namespaceUri, string localName) { IAttr attr = RemoveNamedItemOrDefault(namespaceUri, localName); if (attr == null) throw new DomException(DomError.NotFound); return attr; } public IEnumerator<IAttr> GetEnumerator() { return _items.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _items.GetEnumerator(); } private Attr Prepare(IAttr item) { Attr attr = item as Attr; if (attr != null) { if (attr.Container == this) return null; if (attr.Container != null) throw new DomException(DomError.InUse); attr.Container = this; } return attr; } } }