Skip to content

Commit 4e19dda

Browse files
Denis IvanovDenis Ivanov
authored andcommitted
#18 Fix but without namespaces.
1 parent e2b9f50 commit 4e19dda

File tree

5 files changed

+154
-157
lines changed

5 files changed

+154
-157
lines changed

src/AngleSharp.XPath.Tests/AngleSharp.XPath.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<ItemGroup>
3+
<PackageReference Include="AngleSharp.Xml" Version="0.13.0" />
34
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
45
<PackageReference Include="NUnit" Version="3.12.0" />
56
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,87 @@
1+
using System.Xml;
2+
using AngleSharp.Xml.Parser;
3+
using AngleSharp.Html.Parser;
4+
using NUnit.Framework;
5+
using System.Threading.Tasks;
6+
17
namespace AngleSharp.XPath.Tests
28
{
3-
using AngleSharp.Html.Parser;
4-
using NUnit.Framework;
5-
using System.Threading.Tasks;
6-
79
[TestFixture]
8-
public class HtmlDocumentNavigatorTests
9-
{
10-
[Test, Retry(5)]
11-
public async Task SelectSingleNodeTest()
12-
{
13-
// Arrange
14-
const string address = "https://stackoverflow.com/questions/39471800/is-anglesharps-htmlparser-threadsafe";
15-
var config = Configuration.Default.WithDefaultLoader();
16-
var document = await BrowsingContext.New(config).OpenAsync(address);
10+
public class HtmlDocumentNavigatorTests
11+
{
12+
[Test, Retry(5)]
13+
public async Task SelectSingleNodeTest()
14+
{
15+
// Arrange
16+
const string address = "https://stackoverflow.com/questions/39471800/is-anglesharps-htmlparser-threadsafe";
17+
var config = Configuration.Default.WithDefaultLoader();
18+
var document = await BrowsingContext.New(config).OpenAsync(address);
1719

18-
// Act
19-
var content = document.DocumentElement.SelectSingleNode("//div[@id='content']");
20+
// Act
21+
var content = document.DocumentElement.SelectSingleNode("//div[@id='content']");
2022

21-
// Assert
22-
Assert.That(content, Is.Not.Null);
23-
}
23+
// Assert
24+
Assert.That(content, Is.Not.Null);
25+
}
2426

25-
[Test]
26-
public void SelectNodes_SelectList_ShouldReturnList()
27-
{
28-
// Arrange
29-
const string html =
30-
@"<ol>
27+
[Test]
28+
public void SelectNodes_SelectList_ShouldReturnList()
29+
{
30+
// Arrange
31+
const string html =
32+
@"<ol>
3133
<li>First</li>
3234
<li>Second</li>
3335
<li>Third</li>
3436
</ol>";
35-
var parser = new HtmlParser();
36-
var document = parser.ParseDocument(html);
37+
var parser = new HtmlParser();
38+
var document = parser.ParseDocument(html);
39+
40+
// Act
41+
var nodes = document.DocumentElement.SelectNodes("//li");
3742

38-
// Act
39-
var nodes = document.DocumentElement.SelectNodes("//li");
43+
// Assert
44+
Assert.That(nodes, Has.Count.EqualTo(3));
45+
}
4046

41-
// Assert
42-
Assert.That(nodes, Has.Count.EqualTo(3));
43-
}
44-
4547
[Test]
4648
public void SelectPrecedingNodeInDocumentWithDoctype_ShouldReturnNode()
4749
{
4850
// Arrange
49-
const string html =
50-
@"<!DOCTYPE html>
51+
const string html =
52+
@"<!DOCTYPE html>
5153
<body>
5254
<span></span>
5355
<div></div>
5456
</body>";
55-
var parser = new HtmlParser();
56-
var document = parser.ParseDocument(html);
57+
var parser = new HtmlParser();
58+
var document = parser.ParseDocument(html);
59+
60+
// Act
61+
var node = document.DocumentElement.SelectSingleNode("//div/preceding::span");
62+
63+
// Assert
64+
Assert.That(node, Is.Not.Null);
65+
}
66+
67+
[Test]
68+
public void SelectNodeWithNamespace_ShouldReturnNode()
69+
{
70+
// Arrange
71+
var xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"><url><loc>https://www.test.com/de/accounts/profile</loc><xhtml:link rel=\"alternate\" hreflang=\"fr\" href=\"https://www.test.com/fr/accounts/profile\" /><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://www.test.com/en/accounts/profile\" /><xhtml:link rel=\"alternate\" hreflang=\"it\" href=\"https://www.test.com/it/accounts/profile\" /><changefreq>weekly</changefreq><priority>0.4</priority></url></urlset>";
72+
var parser = new XmlParser();
73+
var doc = parser.ParseDocument(xml);
74+
var namespaceManager = new XmlNamespaceManager(new NameTable());
75+
76+
namespaceManager.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");
77+
namespaceManager.AddNamespace("d", "http://www.sitemaps.org/schemas/sitemap/0.9");
5778

58-
// Act
59-
var node = document.DocumentElement.SelectSingleNode("//div/preceding::span");
79+
// Act
80+
var node = doc.DocumentElement.SelectSingleNode("/urlset/url/link");
6081

61-
// Assert
62-
Assert.That(node, Is.Not.Null);
82+
// Assert
83+
Assert.IsNotNull(node);
84+
Assert.That(node.NodeName, Is.EqualTo("xhtml:link"));
6385
}
64-
}
86+
}
6587
}

src/AngleSharp.XPath/Extensions.cs

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,34 @@
1+
using AngleSharp.Dom;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Diagnostics;
5+
using System.Xml;
6+
using System.Xml.XPath;
7+
18
namespace AngleSharp.XPath
29
{
3-
using AngleSharp.Dom;
4-
using System;
5-
using System.Collections.Generic;
6-
using System.Diagnostics;
7-
using System.Xml;
8-
using System.Xml.XPath;
9-
1010
/// <summary>
1111
/// Hosts the extension methods for XPath parsing.
1212
/// </summary>
1313
public static class Extensions
14-
{
14+
{
1515
/// <summary>
1616
/// Creates a new navigator for the given document.
1717
/// </summary>
1818
/// <param name="document">The document to extend.</param>
1919
/// <returns>The navigator for XPath expressions.</returns>
20-
public static XPathNavigator CreateNavigator(this IDocument document)
21-
{
20+
public static XPathNavigator CreateNavigator(this IDocument document)
21+
{
2222
var doc = document ?? throw new ArgumentNullException(nameof(document));
2323
return new HtmlDocumentNavigator(doc, doc.DocumentElement);
24-
}
25-
26-
[DebuggerStepThrough]
27-
internal static String GetOrAdd(this XmlNameTable table, String array)
28-
{
29-
var s = table.Get(array);
24+
}
3025

31-
if (s == null)
32-
{
33-
return table.Add(array);
34-
}
35-
36-
return s;
37-
}
26+
[DebuggerStepThrough]
27+
internal static string GetOrAdd(this XmlNameTable table, string array)
28+
{
29+
var s = table.Get(array);
30+
return s ?? table.Add(array);
31+
}
3832

3933
/// <summary>
4034
/// Selects a single node (or returns null) matching the <see cref="XPath"/> expression.
@@ -43,21 +37,14 @@ internal static String GetOrAdd(this XmlNameTable table, String array)
4337
/// <param name="xpath">The XPath expression.</param>
4438
/// <returns>The node matching <paramref name="xpath"/> query, if any.</returns>
4539
/// <exception cref="ArgumentNullException">Throws if <paramref name="element"/> or <paramref name="xpath"/> is <c>null</c></exception>
46-
public static INode SelectSingleNode(this IElement element, String xpath)
47-
{
40+
public static INode SelectSingleNode(this IElement element, string xpath)
41+
{
4842
var el = element ?? throw new ArgumentNullException(nameof(element));
4943
var xp = xpath ?? throw new ArgumentNullException(nameof(xpath));
50-
var nav = new HtmlDocumentNavigator(el.Owner, el);
51-
var it = nav.Select(xp);
52-
53-
if (it.MoveNext())
54-
{
55-
var node = (HtmlDocumentNavigator)it.Current;
56-
return node.CurrentNode;
57-
}
58-
59-
return null;
60-
}
44+
var nav = new HtmlDocumentNavigator(el.Owner, el);
45+
var it = nav.SelectSingleNode(xp);
46+
return ((HtmlDocumentNavigator) it)?.CurrentNode;
47+
}
6148

6249
/// <summary>
6350
/// Selects a list of nodes matching the <see cref="XPath"/> expression.
@@ -66,22 +53,24 @@ public static INode SelectSingleNode(this IElement element, String xpath)
6653
/// <param name="xpath">The XPath expression.</param>
6754
/// <returns>List of nodes matching <paramref name="xpath"/> query.</returns>
6855
/// <exception cref="ArgumentNullException">Throws if <paramref name="element"/> or <paramref name="xpath"/> is <c>null</c></exception>
69-
public static List<INode> SelectNodes(this IElement element, String xpath)
56+
public static List<INode> SelectNodes(this IElement element, string xpath)
7057
{
7158
var el = element ?? throw new ArgumentNullException(nameof(element));
7259
var xp = xpath ?? throw new ArgumentNullException(nameof(xpath));
7360
var nav = new HtmlDocumentNavigator(el.Owner, el);
74-
var it = nav.Select(xp);
75-
var result = new List<INode>();
61+
var it = nav.Select(xp);
62+
var result = new List<INode>();
7663

77-
while (it.MoveNext())
78-
{
79-
var naviagtor = (HtmlDocumentNavigator) it.Current;
80-
var e = naviagtor.CurrentNode;
81-
result.Add(e);
82-
}
64+
while (it.MoveNext())
65+
{
66+
// ReSharper disable once IdentifierTypo
67+
var naviagtor = (HtmlDocumentNavigator) it.Current;
68+
// ReSharper disable once PossibleNullReferenceException
69+
var e = naviagtor.CurrentNode;
70+
result.Add(e);
71+
}
8372

84-
return result;
85-
}
86-
}
73+
return result;
74+
}
75+
}
8776
}

src/AngleSharp.XPath/HtmlDocumentNavigable.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
using AngleSharp.Dom;
2+
using System;
3+
using System.Xml.XPath;
4+
15
namespace AngleSharp.XPath
26
{
3-
using AngleSharp.Dom;
4-
using System;
5-
using System.Xml.XPath;
6-
77
/// <inheritdoc />
88
public class HtmlDocumentNavigable : IXPathNavigable
99
{

0 commit comments

Comments
 (0)