Search code examples
c#xmlxpathxmldocument

How to filter data from xml using xmldocument class & xpath


I have xml stored in string variable. from that xml I need to filter data based on StandardValue. I want to extract only those records whose StandardValue is not null & not empty. I tried but my code did not work.

string xmldoc= @"<?xml version=""1.0"" encoding=""utf-8""?>
<TickerBrokerStandardDateLineitem>
  <Ticker />
  <TickerID />
  <TickerBrokerStandardDateLineitemValues>
    <TickerBrokerStandardDateLineitemValue>
      <TabName>Consensus Model</TabName>
      <StandardDate>1Q 2010</StandardDate>
      <BRTab>Income Statement</BRTab>
      <BRLineItem>NET REVENUES</BRLineItem>
      <Action>Extracted</Action>
      <StandardLineItem>Net Revenue</StandardLineItem>
      <StandardValue>329.623</StandardValue>
    </TickerBrokerStandardDateLineitemValue>
    <TickerBrokerStandardDateLineitemValue>
      <TabName>Consensus Model</TabName>
      <StandardDate>2Q 2010</StandardDate>
      <BRTab>Income Statement</BRTab>
      <BRLineItem>NET REVENUES</BRLineItem>
      <Action>Extracted</Action>
      <StandardLineItem>Net Revenue</StandardLineItem>
      <StandardValue></StandardValue>
    </TickerBrokerStandardDateLineitemValue>
    <TickerBrokerStandardDateLineitemValue>
      <TabName>Consensus Model</TabName>
      <StandardDate>2Q 2010</StandardDate>
      <BRTab>Income Statement</BRTab>
      <BRLineItem>NET REVENUES</BRLineItem>
      <Action>Extracted</Action>
      <StandardLineItem>Net Revenue</StandardLineItem>
      <StandardValue/>
    </TickerBrokerStandardDateLineitemValue>
  </TickerBrokerStandardDateLineitemValues>
</TickerBrokerStandardDateLineitem>";

XmlDocument doc = new XmlDocument();
doc.LoadXml(xmldoc);
XmlNodeList nodeList = doc.GetElementsByTagName("TickerBrokerStandardDateLineitemValue");
List<string> list = new List<string>();
foreach (XmlNode item in nodeList)
{
    foreach (XmlElement i in item)
    {
        if (i.Name == "StandardValue")
        {
            if (i.InnerText == string.Empty)
            {
                list.Add(item.OuterXml);
            }
        }
    }
}
string a = string.Empty;
foreach (var item in list)
{
    a = doc.InnerXml.Replace(item, "");
}

string str1 = doc.OuterXml;

My above code does not work. basically how to filter with xpath that return only those records whose StandardValue is not null & not empty.

How to achieve it with XmlDocument class instead of xdocument.

At end I have to stored filtered record's xml into string. I know XmlDocument class has outer xml property which return full xml.

Give me sample code which will return filter records & stored filter records xml into string.


Solution

  • Assuming the input string your provided in the question.

    This will select all TickerBrokerStandardDateLineitemValue values that has StandardValue element and it's not empty or white space (normalize-space).

    normalize-space:

    strips leading and trailing white-space from a string, replaces sequences of whitespace characters by a single space, and returns the resulting string.

    var xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xmlStr); // <input from the question>
    
    var nodes = xmlDoc.SelectNodes("//TickerBrokerStandardDateLineitemValue[StandardValue and string-length(normalize-space(StandardValue))]");