Skip to content

Commit dfd9d33

Browse files
authored
Ability to select attributes. (#31)
1 parent 6e4fc2a commit dfd9d33

File tree

4 files changed

+49
-27
lines changed

4 files changed

+49
-27
lines changed
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<ItemGroup>
3-
<PackageReference Include="AngleSharp.Xml" Version="0.14.0" />
4-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
5-
<PackageReference Include="NUnit" Version="3.12.0" />
6-
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
3+
<PackageReference Include="AngleSharp.Xml" Version="0.16.0" />
4+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
5+
<PackageReference Include="NUnit" Version="3.13.2" />
6+
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
77
</ItemGroup>
88
<ItemGroup>
99
<ProjectReference Include="..\AngleSharp.XPath\AngleSharp.XPath.csproj" />
1010
</ItemGroup>
1111
<PropertyGroup>
12-
<TargetFramework>netcoreapp3.0</TargetFramework>
12+
<TargetFramework>net5.0</TargetFramework>
1313
<IsPackable>false</IsPackable>
1414
</PropertyGroup>
1515
</Project>

src/AngleSharp.XPath.Tests/HtmlDocumentNavigatorTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,22 @@ public void SelectSingleNode_DontIgnoreNamespaces_ShouldReturnNode()
9999
Assert.IsNotNull(node);
100100
Assert.That(node.NodeName, Is.EqualTo("xhtml:link"));
101101
}
102+
103+
[Test]
104+
public void SelectNodes_CanReturnAttribute()
105+
{
106+
// Arrange
107+
var html = "<!DOCTYPE html><html><body><div class=\"one\"><span class=\"two\">hello world</span></div></body></html>";
108+
var parser = new HtmlParser();
109+
var doc = parser.ParseDocument(html);
110+
111+
// Act
112+
var nodes = doc.DocumentElement.SelectNodes("//@*");
113+
114+
// Assert
115+
Assert.IsNotNull(nodes);
116+
Assert.That(nodes, Has.Count.EqualTo(2));
117+
Assert.That(nodes, Is.All.InstanceOf<Dom.IAttr>());
118+
}
102119
}
103120
}

src/AngleSharp.XPath/AngleSharp.XPath.csproj

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<Version>1.1.7</Version>
3+
<Version>2.0.0-alpha-1</Version>
4+
<AssemblyVersion>2.0.0</AssemblyVersion>
5+
<FileVersion>2.0.0-alpha-1</FileVersion>
46
<Authors>Denis Ivanov</Authors>
57
<PackageId>AngleSharp.XPath</PackageId>
6-
<AssemblyVersion>1.1.7</AssemblyVersion>
78
<AssemblyName>AngleSharp.XPath</AssemblyName>
89
<RootNamespace>AngleSharp.XPath</RootNamespace>
9-
<TargetFramework>netstandard2.0</TargetFramework>
10-
<FileVersion>1.1.7</FileVersion>
10+
<TargetFramework>net5.0</TargetFramework>
1111
<Description>XPath support for AngleSharp</Description>
1212
<PackageProjectUrl>https://github.com/AngleSharp/AngleSharp.XPath/</PackageProjectUrl>
1313
<PackageLicenseExpression>MIT</PackageLicenseExpression>
@@ -16,10 +16,11 @@
1616
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
1717
<GenerateDocumentationFile>true</GenerateDocumentationFile>
1818
<PublicSign>True</PublicSign>
19+
<PackageIconUrl>https://raw.githubusercontent.com/AngleSharp/AngleSharp.XPath/master/logo.png</PackageIconUrl>
1920
</PropertyGroup>
2021

2122
<ItemGroup>
22-
<PackageReference Include="AngleSharp" Version="0.14.0" />
23+
<PackageReference Include="AngleSharp" Version="0.16.1-alpha-96" />
2324
</ItemGroup>
2425

2526
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">

src/AngleSharp.XPath/HtmlDocumentNavigator.cs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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,14 +47,14 @@ 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 />
5755
public override string Name =>
58-
_attrIndex != -1
59-
? NameTable.GetOrAdd(CurrentElement.Attributes[_attrIndex].Name)
56+
CurrentNode is IAttr attr
57+
? NameTable.GetOrAdd(attr.Name)
6058
: NameTable.GetOrAdd(_currentNode.NodeName);
6159

6260
/// <inheritdoc />
@@ -69,16 +67,16 @@ public override string NamespaceURI
6967
return string.Empty;
7068
}
7169

72-
return _attrIndex != -1
73-
? NameTable.GetOrAdd(CurrentElement.Attributes[_attrIndex].NamespaceUri ?? string.Empty)
70+
return CurrentNode is IAttr attr
71+
? NameTable.GetOrAdd(attr.NamespaceUri ?? string.Empty)
7472
: NameTable.GetOrAdd(CurrentElement?.NamespaceUri ?? string.Empty);
7573
}
7674
}
7775

7876
/// <inheritdoc />
7977
public override string Prefix =>
80-
_attrIndex != 1
81-
? NameTable.GetOrAdd(CurrentElement.Attributes[_attrIndex].Prefix ?? string.Empty)
78+
CurrentNode is IAttr attr
79+
? NameTable.GetOrAdd(attr.Prefix ?? string.Empty)
8280
: NameTable.GetOrAdd(CurrentElement?.Prefix ?? string.Empty);
8381

8482
/// <inheritdoc />
@@ -107,7 +105,7 @@ public override XPathNodeType NodeType
107105
return XPathNodeType.Element;
108106

109107
case Dom.NodeType.Element:
110-
return _attrIndex != -1 ? XPathNodeType.Attribute : XPathNodeType.Element;
108+
return XPathNodeType.Element;
111109

112110
case Dom.NodeType.ProcessingInstruction:
113111
return XPathNodeType.ProcessingInstruction;
@@ -155,7 +153,7 @@ public override string Value
155153
return documentType.Name;
156154

157155
case Dom.NodeType.Element:
158-
return _attrIndex != -1 ? CurrentElement.Attributes[_attrIndex].Value : _currentNode.TextContent;
156+
return _currentNode.TextContent;
159157

160158
case Dom.NodeType.Entity:
161159
return _currentNode.TextContent;
@@ -207,7 +205,6 @@ public override bool MoveTo(XPathNavigator other)
207205
if (navigator._document == _document)
208206
{
209207
_currentNode = navigator._currentNode;
210-
_attrIndex = navigator._attrIndex;
211208
return true;
212209
}
213210

@@ -218,8 +215,8 @@ public override bool MoveTo(XPathNavigator other)
218215
public override bool MoveToFirstAttribute()
219216
{
220217
if (HasAttributes)
221-
{
222-
_attrIndex = 0;
218+
{
219+
_currentNode = CurrentElement.Attributes[0];
223220
return true;
224221
}
225222

@@ -278,12 +275,19 @@ public override bool MoveToNextAttribute()
278275
return false;
279276
}
280277

281-
if (_attrIndex >= CurrentElement.Attributes.Length - 1)
278+
if (!(CurrentNode is IAttr attr))
279+
{
280+
return false;
281+
}
282+
283+
var attrIndex = attr.OwnerElement.Attributes.Index(attr);
284+
285+
if (attrIndex >= CurrentElement.Attributes.Length - 1)
282286
{
283287
return false;
284288
}
285289

286-
_attrIndex++;
290+
_currentNode = attr.OwnerElement.Attributes[attrIndex + 1];
287291
return true;
288292
}
289293

0 commit comments

Comments
 (0)