Basically I just want to check if the last element in the XML document I have is called
<element99>
or not, and if so, read its attributes. What would be the most efficient way to do so?
Is there a way not to load entire XML doc into memory?
CodePudding user response:
You could evaluate the XPath expression boolean(/*/*[last()]/self::element99)
which returns true
if the last element contained in the root element is named element99
. The expression /*/*[last()]/self::element99/@*
returns the attributes of that element.
CodePudding user response:
In XPath you could do (//*)[last()][self::element99]/@*
or you could do //element99[not(following::*)]/@*
- but this isn't quite the same thing - it will match an element99 that has children, and depending what you mean by "last", an element with children is never the last element in the document.
CodePudding user response:
You can use System.Xml.XmlReader
.
In this approach the file will be read element-by-element and will not be loaded fully in the memory.
The following method checks if an <element99>
exists, and if it is the last element.
bool CheckXml(string path)
{
XmlReader xmlReader = XmlReader.Create(new StreamReader(path));
if (!xmlReader.ReadToFollowing("element99"))
return false;
if (xmlReader.NodeType != XmlNodeType.Element)
return false;
xmlReader.Skip();
while (!xmlReader.EOF)
{
if (xmlReader.NodeType != XmlNodeType.EndElement && xmlReader.NodeType != XmlNodeType.Whitespace)
{
return false;
}
xmlReader.Read();
}
return true;
}
Since XmlReader only provides forward-only access, you have to
- Read and store attributes before checking if the element is the last one.
- Read the stream again and store the required attributes.