Reputation: 21
I am trying to get the elements title and runtime (siblings) where the runtime value is larger than the input value. My C# code with the XPath expression is:
ElementValue = 140;
nodeList = root.SelectNodes(@"/moviedb/movie[./runtime>'" + ElementValue + "'/title | /moviedb/movie[./runtime>'" + ElementValue + "']/runtime");
This XPath expression is not returning anything.
My XML file:
<moviedb>
<movie>
<imdbid>tt0120689</imdbid>
<genres>Crime,Drama,Fantasy,Mystery</genres>
<languages>English,French</languages>
<country>USA</country>
<rating>8.5</rating>
<runtime>189</runtime>
<title lang="english">The Green Mile</title>
<year>1999</year>
</movie>
<movie>
<imdbid>tt0415800</imdbid>
<genres>Action,Animation,Drama,Thriller</genres>
<languages>English</languages>
<country>USA</country>
<rating>4.5</rating>
<runtime>139</runtime>
<title lang="english">Fight Club</title>
<year>2004</year>
</movie>
</moviedb>
Upvotes: 2
Views: 100
Reputation: 3517
You can do this using a single XPath expression by performing a union
i.e. the |
operator. As mentioned in other answers here, you had your select inside your predicate which would not result in the correct answer for you anyway.
Note, if you want to see if a number is bigger than another number, unless you are using a Schema driven data-type aware XQuery engine you will need to cast the text()
to a number before performing the comparison. In this instance I have assumed an xs:int
will be suitable for you. Also you can use the atomic gt
as opposed to =
which may be more efficient.
ElementValue = 140;
nodeList = root.SelectNodes(@"/moviedb/movie[xs:int(runtime) gt " + ElementValue + "]/(title | runtime)");
Upvotes: 1
Reputation: 107357
You seem to be applying the values you want off the node as a filter criteria, which won't work. I would go about this another way, first finding the nodes which meet the criteria:
nodeList = root.SelectNodes(@"/moviedb/movie[runtime > " + ElementValue + "]");
And then grabbing the child elements from each:
foreach (var node in nodeList)
{
Debug.WriteLine(node.SelectSingleNode("title").InnerText);
Debug.WriteLine(node.SelectSingleNode("runtime").InnerText);
}
Upvotes: 1
Reputation: 32817
You can instead use linq2xml
var doc=XDocument.Load(path);
var movies=doc.Elements("movie")
.Where(x=>(int)x.Element("runtime")>input)
.Select(x=>new
{
Title=x.Element("title").Value,
Runtime=(int)x.Element("runtime")
});
You can now iterate over movies
foreach(var movie in movies)
{
movie.Title;
movie.Runtime;
}
Upvotes: 2