You can read the first <Name>
element inside each <InformationTuple>
as follows. Introduce the following extension methods:
public static partial class XmlReaderExtensions
{
public static IEnumerable<string> ReadAllElementContentsAsString(this XmlReader reader, string localName, string namespaceURI)
{
while (reader.ReadToFollowing(localName, namespaceURI))
yield return reader.ReadElementContentAsString();
}
public static IEnumerable<XmlReader> ReadAllSubtrees(this XmlReader reader, string localName, string namespaceURI)
{
while (reader.ReadToFollowing(localName, namespaceURI))
using (var subReader = reader.ReadSubtree())
yield return subReader;
}
}
And then do:
foreach (var name in reader.ReadAllSubtrees("InformationTuple", "")
.Select(r => r.ReadAllElementContentsAsString("Name", "").First()))
{
// Process the name somehow
Debug.WriteLine(name);
}
If you want to only read the first <Name>
element of each <InformationTuple>
element inside each <InformationTuples>
container, you can restrict the scope of the search by composing calls to ReadAllSubtrees()
using SelectMany()
:
foreach (var name in reader.ReadAllSubtrees("InformationTuples", "")
.SelectMany(r => r.ReadAllSubtrees("InformationTuple", ""))
.Select(r => r.ReadAllElementContentsAsString("Name", "").First()))
{
// Process the name somehow
Debug.WriteLine(name);
}
Some notes:
You don't close (or dispose) your ReadSubtree()
subtree reader when you are done with it. From the docs:
You should not perform any operations on the original reader until the new reader has been closed. This action is not supported and can result in unpredictable behavior.
Thus you must close or dispose this nested reader before advancing the outer reader.
You have too many calls to reader.ReadToFollowing("InformationTuple");
at the beginning. Perhaps you meant to do reader.ReadToFollowing("InformationTuples");
?
To ensure there is one and only one <Name>
element for each <InformationTuple>
replace First()
with .Single()
.
If there might be multiple <Name>
nodes for each <InformationTuple>
and you want to read all of them, do:
foreach (var name in reader.ReadAllSubtrees("InformationTuple", "")
.SelectMany(r => r.ReadAllElementContentsAsString("Name", "")))
{
// Process the name somehow
Demo fiddle here.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…