Reputation: 1503
I am new to using LINQ and am trying to select a node from an XML document that i've transformed.
here is the raw code:
// create a LINQ xml doc
XDocument xdoc = XDocument.Parse(xTransformedDoc.OuterXml);
// get sibling elements to the shredding element
IEnumerable<XElement> xe = xdoc.Root.XPathSelectElements("//" + settings.ShredNode + "[1]/(following-sibling|preceding-sibling)[name() != '" + settings.ShredNode + "']");
Note: earlier in the code settings.ShredNode is set to "DocRouteDetail"
at first i thought it was a problem with the complexity of the xpath statement i am using however i've tried every combination i can think of and even rolled it back to absolute basics in the VS debugger:
xdoc.Root.XPathSelectElements(".")
xdoc.Root.XPathSelectElements("//DocRouteDetail")
etc
in all cases it returns back null and it generates an exception returning "Expression must evaluate to a node-set."
this is happening in .NET framework 4.0 in c#.
i have checked and the xdoc.Root variable is not null and my xml looks like the following (full document slimmed down for security reasons):
<DocFWImport xmlns:dtfn2="urn:my-scripts2">
<Header SendDateTime="2014-04-03T19:26:50" />
<Request>
<DocRouteDetail MessagePurpose="1002" ResourceKey="A" >
<DocStop StopNumber="0" Type="0" LocationType="DEPOT">
</DocStop>
<DocStop StopNumber="1" Type="3" LocationType="CUSTOMER" >
</DocStop>
<DocStop StopNumber="2" Type="0" LocationType="DEPOT">
</DocStop>
</DocRouteDetail>
<parmRouteTemplateKey>TEAM</parmRouteTemplateKey>
<DocRouteDetail MessagePurpose="1002" ResourceKey="B" >
<DocStop StopNumber="0" Type="0" LocationType="DEPOT">
</DocStop>
<DocStop StopNumber="1" Type="3" LocationType="CUSTOMER" >
</DocStop>
<DocStop StopNumber="2" Type="0" LocationType="DEPOT">
</DocStop>
</DocRouteDetail>
<parmRouteTemplateKey>SINGLE</parmRouteTemplateKey>
etc
</Request>
</DocFWImport>
it should have returned the 2 parmRouteTemplateKey elements.
Upvotes: 0
Views: 1734
Reputation: 89285
As pointed by @pjotr, your XPath attempt is not valid. You can try to combine 2 XPaths using union operator (|
) like this instead :
var xpath1 = "//" + settings.ShredNode
+ "[1]/following-sibling[name() != '" + settings.ShredNode + "']";
var xpath2 = "//" + settings.ShredNode
+ "[1]/preceding-sibling[name() != '" + settings.ShredNode + "']";
IEnumerable<XElement> xe =
xdoc.Root
.XPathSelectElements(xpath1 + " | " + xpath2);
Upvotes: 0
Reputation: 2579
It's not the XPathSelectElements
's fault, your XPath query is invalid - namely the part with the |
operator. The other basic queries you're mentioning do work. If they really don't, then there's some another error outside the code you've posted.
I'd write it as
//DocRouteDetail[1]/parent::*/child::*[name()!='DocRouteDetail']
that way it selects what you need.
Upvotes: 1