diff --git a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/Program.cs b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/Program.cs
index 9aa91deee0..39a30c440d 100644
--- a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/Program.cs
+++ b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/Program.cs
@@ -1,13 +1,16 @@
using SelectingXmlNodesWithXpath;
using System.Xml;
+using System.Xml.Linq;
+
+var path = Path.Combine(AppContext.BaseDirectory, "BooksCatalog.xml");
var doc = new XmlDocument();
-doc.Load("BooksCatalog.xml");
+doc.Load(path);
var root = doc.DocumentElement!;
Console.WriteLine("Selected book:");
var singleResult = XmlNodesSelector.SelectSingleBook(root);
-Console.WriteLine(singleResult);
+Console.WriteLine(singleResult ?? "No book matched the query.");
Console.WriteLine("\nSelected books:");
var results = XmlNodesSelector.SelectBooks(root);
@@ -15,4 +18,8 @@
Console.WriteLine("\nSelected books:");
var resultsFromNamespaces = XmlNodesSelector.SelectBooksUsingNamespaces(doc);
-resultsFromNamespaces.ForEach(Console.WriteLine);
\ No newline at end of file
+resultsFromNamespaces.ForEach(Console.WriteLine);
+
+Console.WriteLine("\nSelected books with LINQ to XML:");
+var linqResults = XmlNodesSelector.SelectBooksWithLinqToXml(XDocument.Load(path));
+linqResults.ForEach(Console.WriteLine);
diff --git a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath.csproj b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath.csproj
index 13e09a4050..b894a2e9cc 100644
--- a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath.csproj
+++ b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath.csproj
@@ -2,7 +2,7 @@
Exe
- net7.0
+ net10.0
enable
enable
diff --git a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/XmlNodesSelector.cs b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/XmlNodesSelector.cs
index 0dcd38eb02..ef7d7e2009 100644
--- a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/XmlNodesSelector.cs
+++ b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpath/XmlNodesSelector.cs
@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Linq;
+using System.Xml.XPath;
namespace SelectingXmlNodesWithXpath;
@@ -10,18 +11,23 @@ public static string FormatXml(string unformattedXml)
return XElement.Parse(unformattedXml).ToString();
}
- public static string SelectSingleBook(XmlNode root)
+ public static string? SelectSingleBook(XmlNode root)
{
var node = root.SelectSingleNode("//catalog/book[position()=2]");
-
- return FormatXml(node!.OuterXml);
+
+ return node is null ? null : FormatXml(node.OuterXml);
}
public static List SelectBooks(XmlNode root)
{
var nodes = root.SelectNodes("//catalog/book[price<50.00]");
- return nodes!
+ if (nodes is null)
+ {
+ return [];
+ }
+
+ return nodes
.Cast()
.Select(x => FormatXml(x.OuterXml))
.ToList();
@@ -34,9 +40,22 @@ public static List SelectBooksUsingNamespaces(XmlDocument doc)
var nodes = doc.SelectNodes("descendant::ex:book", nsmgr);
- return nodes!
+ if (nodes is null)
+ {
+ return [];
+ }
+
+ return nodes
.Cast()
.Select(x => FormatXml(x.OuterXml))
.ToList();
}
+
+ public static List SelectBooksWithLinqToXml(XDocument doc)
+ {
+ return doc
+ .XPathSelectElements("//catalog/book[price<50.00]")
+ .Select(x => x.ToString())
+ .ToList();
+ }
}
diff --git a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/GlobalUsings.cs b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/GlobalUsings.cs
index 47c68f284e..6f54963f00 100644
--- a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/GlobalUsings.cs
+++ b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/GlobalUsings.cs
@@ -1,3 +1,4 @@
global using SelectingXmlNodesWithXpath;
global using System.Xml;
-global using Xunit;
\ No newline at end of file
+global using Xunit;
+global using System.Xml.Linq;
diff --git a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/Tests.csproj b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/Tests.csproj
index 4d8871fd89..aa17d0c4ed 100644
--- a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/Tests.csproj
+++ b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/Tests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net10.0
enable
enable
@@ -16,13 +16,13 @@
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/XmlNodesSelectorTest.cs b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/XmlNodesSelectorTest.cs
index ae42800b5b..7334e77458 100644
--- a/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/XmlNodesSelectorTest.cs
+++ b/xml-csharp/SelectingXmlNodesWithXpath/SelectingXmlNodesWithXpathTests/XmlNodesSelectorTest.cs
@@ -64,7 +64,7 @@ public void GivenAnXmlFile_WhenSelectingASingleNode_ThenReturnsTheSecondPosition
{
var result = XmlNodesSelector.SelectSingleBook(_document.DocumentElement!);
- Assert.Equal(result, _expectedResults["Book2"]);
+ Assert.Equal(result?.ReplaceLineEndings(), _expectedResults["Book2"].ReplaceLineEndings());
}
[Fact]
@@ -72,10 +72,12 @@ public void GivenAnXmlFile_WhenSelectingNodes_ThenReturnBooksWithPriceLowerThan5
{
var expected = _expectedResults
.Where(pair => pair.Key is "Book1" or "Book3")
- .Select(pair => pair.Value)
+ .Select(pair => pair.Value.ReplaceLineEndings())
.ToList();
- var result = XmlNodesSelector.SelectBooks(_document.DocumentElement!);
+ var result = XmlNodesSelector.SelectBooks(_document.DocumentElement!)
+ .Select(x => x.ReplaceLineEndings())
+ .ToList();
Assert.Equal(result, expected);
}
@@ -86,11 +88,53 @@ public void GivenAnXmlFile_WhenSelectingNodesUsingNamespaces_ThenReturnBookEleme
var expected =
_expectedResults
.Where(pair => pair.Key is "Book4")
- .Select(pair => pair.Value)
+ .Select(pair => pair.Value.ReplaceLineEndings())
.ToList();
- var result = XmlNodesSelector.SelectBooksUsingNamespaces(_document);
+ var result = XmlNodesSelector.SelectBooksUsingNamespaces(_document)
+ .Select(x => x.ReplaceLineEndings())
+ .ToList();
Assert.Equal(result, expected);
}
-}
\ No newline at end of file
+
+ [Fact]
+ public void GivenAnXmlFile_WhenSelectSingleNodeMatchesNothing_ThenReturnsNull()
+ {
+ var node = _document.DocumentElement!.SelectSingleNode("//catalog/book[price>1000]");
+
+ Assert.Null(node);
+ }
+
+ [Fact]
+ public void GivenAnXmlFile_WhenSelectNodesMatchesNothing_ThenReturnsAnEmptyList()
+ {
+ var nodes = _document.DocumentElement!.SelectNodes("//catalog/book[price>1000]");
+
+ Assert.NotNull(nodes);
+ Assert.Equal(0, nodes.Count);
+ }
+
+ [Fact]
+ public void GivenABookInADefaultNamespace_WhenQueryingWithAnUnprefixedName_ThenReturnsThreeOfTheFourBooks()
+ {
+ var nodes = _document.DocumentElement!.SelectNodes("//catalog/book");
+
+ Assert.NotNull(nodes);
+ Assert.Equal(3, nodes.Count);
+ }
+
+ [Fact]
+ public void GivenAnXDocument_WhenSelectingWithXPathSelectElements_ThenReturnsTheSameBooksAsSelectNodes()
+ {
+ var expected = XmlNodesSelector.SelectBooks(_document.DocumentElement!)
+ .Select(x => x.ReplaceLineEndings())
+ .ToList();
+
+ var result = XmlNodesSelector.SelectBooksWithLinqToXml(XDocument.Load("BooksCatalog.xml"))
+ .Select(x => x.ReplaceLineEndings())
+ .ToList();
+
+ Assert.Equal(expected, result);
+ }
+}