@@ -10,7 +10,6 @@ public class HtmlDocumentNavigator : XPathNavigator
1010 {
1111 private readonly IDocument _document ;
1212 private INode _currentNode ;
13- private int _attrIndex ;
1413 private readonly bool _ignoreNamespaces ;
1514
1615 /// <summary>
@@ -24,7 +23,6 @@ public HtmlDocumentNavigator(IDocument document, INode currentNode, bool ignoreN
2423 _document = document ?? throw new ArgumentNullException ( nameof ( document ) ) ;
2524 NameTable = new NameTable ( ) ;
2625 _currentNode = currentNode ?? throw new ArgumentNullException ( nameof ( currentNode ) ) ;
27- _attrIndex = - 1 ;
2826 _ignoreNamespaces = ignoreNamespaces ;
2927 }
3028
@@ -49,15 +47,28 @@ public HtmlDocumentNavigator(IDocument document, INode currentNode, bool ignoreN
4947
5048 /// <inheritdoc />
5149 public override string LocalName =>
52- _attrIndex != - 1
53- ? NameTable . GetOrAdd ( CurrentElement . Attributes [ _attrIndex ] . LocalName )
50+ CurrentNode is IAttr attr
51+ ? attr . LocalName
5452 : NameTable . GetOrAdd ( CurrentNode is IElement e ? e . LocalName : string . Empty ) ;
5553
5654 /// <inheritdoc />
57- public override string Name =>
58- _attrIndex != - 1
59- ? NameTable . GetOrAdd ( CurrentElement . Attributes [ _attrIndex ] . Name )
60- : NameTable . GetOrAdd ( _currentNode . NodeName ) ;
55+ public override string Name
56+ {
57+ get
58+ {
59+ if ( CurrentNode is IAttr attr )
60+ {
61+ return NameTable . GetOrAdd ( attr . Name ) ;
62+ }
63+
64+ if ( CurrentElement != null )
65+ {
66+ return NameTable . GetOrAdd ( CurrentElement . LocalName ) ;
67+ }
68+
69+ return NameTable . GetOrAdd ( _currentNode . NodeName ) ;
70+ }
71+ }
6172
6273 /// <inheritdoc />
6374 public override string NamespaceURI
@@ -69,16 +80,16 @@ public override string NamespaceURI
6980 return string . Empty ;
7081 }
7182
72- return _attrIndex != - 1
73- ? NameTable . GetOrAdd ( CurrentElement . Attributes [ _attrIndex ] . NamespaceUri ?? string . Empty )
83+ return CurrentNode is IAttr attr
84+ ? NameTable . GetOrAdd ( attr . NamespaceUri ?? string . Empty )
7485 : NameTable . GetOrAdd ( CurrentElement ? . NamespaceUri ?? string . Empty ) ;
7586 }
7687 }
7788
7889 /// <inheritdoc />
7990 public override string Prefix =>
80- _attrIndex != 1
81- ? NameTable . GetOrAdd ( CurrentElement . Attributes [ _attrIndex ] . Prefix ?? string . Empty )
91+ CurrentNode is IAttr attr
92+ ? NameTable . GetOrAdd ( attr . Prefix ?? string . Empty )
8293 : NameTable . GetOrAdd ( CurrentElement ? . Prefix ?? string . Empty ) ;
8394
8495 /// <inheritdoc />
@@ -107,7 +118,7 @@ public override XPathNodeType NodeType
107118 return XPathNodeType . Element ;
108119
109120 case Dom . NodeType . Element :
110- return _attrIndex != - 1 ? XPathNodeType . Attribute : XPathNodeType . Element ;
121+ return XPathNodeType . Element ;
111122
112123 case Dom . NodeType . ProcessingInstruction :
113124 return XPathNodeType . ProcessingInstruction ;
@@ -155,7 +166,7 @@ public override string Value
155166 return documentType . Name ;
156167
157168 case Dom . NodeType . Element :
158- return _attrIndex != - 1 ? CurrentElement . Attributes [ _attrIndex ] . Value : _currentNode . TextContent ;
169+ return _currentNode . TextContent ;
159170
160171 case Dom . NodeType . Entity :
161172 return _currentNode . TextContent ;
@@ -207,7 +218,6 @@ public override bool MoveTo(XPathNavigator other)
207218 if ( navigator . _document == _document )
208219 {
209220 _currentNode = navigator . _currentNode ;
210- _attrIndex = navigator . _attrIndex ;
211221 return true ;
212222 }
213223
@@ -218,8 +228,8 @@ public override bool MoveTo(XPathNavigator other)
218228 public override bool MoveToFirstAttribute ( )
219229 {
220230 if ( HasAttributes )
221- {
222- _attrIndex = 0 ;
231+ {
232+ _currentNode = CurrentElement . Attributes [ 0 ] ;
223233 return true ;
224234 }
225235
@@ -278,12 +288,24 @@ public override bool MoveToNextAttribute()
278288 return false ;
279289 }
280290
281- if ( _attrIndex >= CurrentElement . Attributes . Length - 1 )
291+ if ( ! ( CurrentNode is IAttr attr ) )
292+ {
293+ return false ;
294+ }
295+
296+ if ( attr . OwnerElement == null )
297+ {
298+ return false ;
299+ }
300+
301+ var attrIndex = attr . OwnerElement . Attributes . Index ( attr ) ;
302+
303+ if ( attrIndex >= CurrentElement . Attributes . Length - 1 )
282304 {
283- return false ;
305+ return false ;
284306 }
285307
286- _attrIndex ++ ;
308+ _currentNode = attr . OwnerElement . Attributes [ attrIndex + 1 ] ;
287309 return true ;
288310 }
289311
@@ -296,6 +318,12 @@ public override bool MoveToNextNamespace(XPathNamespaceScope namespaceScope)
296318 /// <inheritdoc />
297319 public override bool MoveToParent ( )
298320 {
321+ if ( CurrentNode is IAttr attr )
322+ {
323+ _currentNode = attr . OwnerElement ;
324+ return true ;
325+ }
326+
299327 if ( _currentNode . Parent == null )
300328 {
301329 return false ;
0 commit comments