0

I would like to extract data from XML and convert it to a DateTime through XPaths. I have following function:

DateTime? GetXPathDate(string xPath, XDocument xDoc)
{
    DateTime? result = null;
    var element = xDoc.XPathSelectElement(xPath);
    return result;
}

I can find the element but the issue it is wrapped in an CData:

<CarName>
    <![CDATA[XXX Jan]]>
</CarName>

Is there anyway to ignore the CData part via the XDocument or do I need to regex my self out of this?

dbc
  • 104,963
  • 20
  • 228
  • 340
Thomas Segato
  • 4,567
  • 11
  • 55
  • 104
  • Your example is unclear - you've shown the document, but not the xpath you expect to find the data (or even what the data is that you're looking for). Please provide a clearer, more complete example. – Jon Skeet Mar 19 '21 at 17:29
  • System.Xml.Linq already knows how to work with CDATA through [XCData](https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xcdata?view=net-5.00). You don't need to regex or anything. – Crowcoder Mar 19 '21 at 17:35
  • To select a `CData` text value, see [How do I retrieve element text inside CDATA markup via XPath?](https://stackoverflow.com/q/568315/3744182) or [How do i read individual xml nodes from a node that contains both CDATA and xml](https://stackoverflow.com/q/12790752/3744182). Do those answer your question? – dbc Mar 19 '21 at 17:48
  • I tried /Root/Car/CarName/text() but thorws following: The XPath expression evaluated to unexpected type System.Xml.Linq.XCData. I saw that post but failed to succeed. – Thomas Segato Mar 19 '21 at 18:19
  • @Crowcoder but can you incorporate that into an XPath? – Thomas Segato Mar 19 '21 at 18:24
  • 1
    It is extremely rare that I use XPath, but when I just mocked up a sample, XElement is smart enough to provide the cdata content as the Value. So, if your xpath is correct, the string you need to parse to a date is simply `element.Value` – Crowcoder Mar 19 '21 at 18:49
  • Right, I guess you have to use [`XPathEvaluate`](https://learn.microsoft.com/en-us/dotnet/api/system.xml.xpath.extensions.xpathevaluate?view=net-5.0) to select an `XCData` node directly. But anyway Crowcoder is right, it's easiest to select with the xpath `"/Root/Car/CarName"` and then just use `element.Value`, e.g. `XmlConvert.ToDateTime(element.Value, XmlDateTimeSerializationMode.RoundtripKind);`. Be sure to parse in an invariant context unless you know the XML was formatted with localized dates. – dbc Mar 19 '21 at 19:25
  • Yes just realized the Value actually allready parses it. Can you throw an anwser. Thanks alot. – Thomas Segato Mar 20 '21 at 06:08

1 Answers1

0

Please try the following conceptual example.

c#

void Main()
{
    string elementName = "CarName";
    
    XElement xelem = XElement.Parse("<CarName><![CDATA[XXX Jan]]></CarName>");
    
    XElement x = xelem.DescendantsAndSelf(elementName).FirstOrDefault();
    Console.WriteLine(x.Value);
}

Output

XXX Jan
Yitzhak Khabinsky
  • 18,471
  • 2
  • 15
  • 21