freshbm
freshbm

Reputation: 5622

Convert LinqToXml expression to XPath

I have this linq expression that I need to convert to XPath select element:

XElement transIdElement = (from criteria in searchCriteria.Descendants("CRITERIA") 
                           where criteria.Element("DataPointName).Value == "TransactionNumber" 
                           select criteria.Element("CriteriaComparisonValue")).FirstOrDefault();

and I tried with this:

var transIdElement = searchCriteria.XPathSelectElement("//CRITERIA/DataPointName[text() = 'TransactionNumber']/CriteriaComparisonValue");

but I get null as result.

XML sample is:

<SEARCH>
    <ADVANCED_CRITERIA>
        <CRITERIA>
            <DataPointName>TransactionNumber</DataPointName>
            <CriteriaComparisonValue>12457845</CriteriaComparisonValue>
        </CRITERIA>
     </ADVANCED_CRITERIA>
</SEARCH>

Upvotes: 0

Views: 122

Answers (3)

har07
har07

Reputation: 89285

A more accurate XPath translation of your LINQ-to-XML query would be as follow :

//CRITERIA[DataPointName = 'TransactionNumber']/CriteriaComparisonValue

Here is a glimpse of how the above predicate expression (expression in square brackets) works.

DataPointName references child element named "DataPointName" of the context element. In this particular predicate, the context element is CRITERIA.

'TransactionNumber' with quotes surround means literal-string in XPath. When an element compared to a string in XPath, the element is translated into string by calling XPath string() function.

Upvotes: 1

Cetin Basoz
Cetin Basoz

Reputation: 23797

void Main()
{
    string xml = @"<SEARCH>
    <ADVANCED_CRITERIA>
        <CRITERIA>
            <DataPointName>TransactionNumber</DataPointName>
            <CriteriaComparisonValue>12457845</CriteriaComparisonValue>
        </CRITERIA>
     </ADVANCED_CRITERIA>
</SEARCH>";
    var searchCriteria = XElement.Parse(xml);
   searchCriteria.XPathSelectElements("//CRITERIA[DataPointName='TransactionNumber']/CriteriaComparisonValue").Dump();
}

Upvotes: 2

rbm
rbm

Reputation: 3253

Use .. to access parent::node() and try

//CRITERIA/DataPointName[text() = 'TransactionNumber']/../CriteriaComparisonValue

quick test in LINQpad:

var f = @"c:\temp\x\a.xml";
var searchCrit = XDocument.Load(f);
searchCrit.XPathSelectElement("//CRITERIA/DataPointName[text() = 'TransactionNumber']/../CriteriaComparisonValue").Value.Dump();

produces

12457845

Upvotes: 2

Related Questions