说我有这个XML:
<fields>
<field fieldid="fdtElem3Group">
<value actionid="1" actiontype="review">123456789</value>
<value actionid="2" actiontype="review">123456789</value>
<value actionid="3" actiontype="review">123456789</value>
<value actionid="4" actiontype="review">123456789</value>
<value actionid="5" actiontype="review">123456789</value>
</field>
<field fieldid="fdtElem7Group">
<value actionid="1" actiontype="review">29/10/75</value>
<value actionid="2" actiontype="review">29/10/74</value>
<value actionid="3" actiontype="review">29/10/74</value>
<value actionid="4" actiontype="review">29/10/76</value>
<value actionid="5" actiontype="review">29/10/74</value>
</field>
</fields>
我正在尝试使用XmlReader
获取每个相应“字段”元素的最后一个'value'元素的值。我该怎么办?这不起作用:
while (xmlReader.Read())
{
if ((xmlReader.NodeType == System.Xml.XmlNodeType.Element) && (xmlReader.Name == "field"))
{
xmlReader.ReadToDescendant("value");
while (xmlReader.ReadToNextSibling("value"))
{
//just iterate over until it reaches the end
}
xmlReader.Read();
Console.WriteLine(xmlReader.Value);
}
}
答案 0 :(得分:1)
很抱歉,现在阅读您正在寻找xmReader解决方案。但是使用XDocument和Linq,您可以执行以下操作:
string xml = @"<fields>
<field fieldid=""fdtElem3Group"">
<value actionid=""1"" actiontype=""review"">123456789</value>
<value actionid=""2"" actiontype=""review"">123456789</value>
<value actionid=""3"" actiontype=""review"">123456789</value>
<value actionid=""4"" actiontype=""review"">123456789</value>
<value actionid=""5"" actiontype=""review"">123456789</value>
</field>
<field fieldid=""fdtElem7Group"">
<value actionid=""1"" actiontype=""review"">29/10/75</value>
<value actionid=""2"" actiontype=""review"">29/10/74</value>
<value actionid=""3"" actiontype=""review"">29/10/74</value>
<value actionid=""4"" actiontype=""review"">29/10/76</value>
<value actionid=""5"" actiontype=""review"">29/10/74</value>
</field>
</fields>";
var xmlDoc = XDocument.Parse(xml).Root;
var lastElements = xmlDoc.Descendants("field").Select(x => x.LastNode);
答案 1 :(得分:1)
希望这有帮助!
static void Main(string[] args)
{
string xml = @"<fields><field fieldid='fdtElem3Group'><value actionid='1' actiontype='review'>123456789</value><value actionid='2' actiontype='review'>123456789</value><value actionid='3' actiontype='review'>123456789</value><value actionid='4' actiontype='review'>123456789</value><value actionid='5' actiontype='review'>123456789</value></field><field fieldid='fdtElem7Group'><value actionid='1' actiontype='review'>29/10/75</value> <value actionid='2' actiontype='review'>29/10/74</value><value actionid='3' actiontype='review'>29/10/74</value><value actionid='4' actiontype='review'>29/10/76</value><value actionid='5' actiontype='review'>29/10/74</value></field></fields>";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
foreach (XmlNode item in xmlDocument.DocumentElement.ChildNodes)
{
Console.WriteLine(item.LastChild.InnerXml);
}
Console.ReadKey();
}
答案 2 :(得分:1)
如果您不想将整个XML加载到XDocument
(因为它非常大),您可以采用混合方法,使用XmlReader
来迭代XML文件中的<field>
和<value>
元素,将每个<value>
元素加载到XElement
,然后选择每个父<field>
的最后一个元素。无论XML文件增长多大,这都会使内存占用量保持很小且不变。
首先介绍以下两种扩展方法:
public static class XmlReaderExtensions
{
public static IEnumerable<IEnumerable<XElement>> ReadNestedElements(this XmlReader xmlReader, string outerName, string innerName)
{
while (!xmlReader.EOF)
{
if (xmlReader.NodeType == System.Xml.XmlNodeType.Element && xmlReader.Name == outerName)
{
using (var subReader = xmlReader.ReadSubtree())
{
yield return subReader.ReadElements(innerName);
}
}
xmlReader.Read();
}
}
public static IEnumerable<XElement> ReadElements(this XmlReader xmlReader, string name)
{
while (!xmlReader.EOF)
{
if (xmlReader.NodeType == System.Xml.XmlNodeType.Element && xmlReader.Name == name)
{
var element = (XElement)XNode.ReadFrom(xmlReader);
yield return element;
}
else
{
xmlReader.Read();
}
}
}
}
然后你的算法得到最后的价值&#39;每个领域的元素&#39;元素变得非常简单:
public static List<string> LastFieldValues(XmlReader reader)
{
var query = reader.ReadNestedElements("field", "value")
.Select(l => l.LastOrDefault())
.Where(v => v != null)
.Select(v => (string)v);
return query.ToList();
}
注意:
XmlReaderExtensions.ReadNestedElements()
返回属于<value>
元素的<field>
个元素的可枚举数。然后使用Enumerable.LastOrDefault()
选择属于每个<value>
的最后一个<field>
。
XmlReader.ReadSubtree()
使XmlReader
位于位于正在读取的元素的EndElement
节点上,而XNode.ReadFrom()
会将读取器放置在位置紧跟正在读取的元素的EndElement
节点之后。只是一个烦人的不一致,需要注意。
另一方面,如果您愿意将整个XML作为XDocument
加载到内存中,可以使用XPathSelectElements()
非常简单地完成此操作:
// Parse the XML into an XDocument.
// You can use use XDocument.Load(fileName) to load from a file
var doc = XDocument.Parse(xmlString);
var xpathLastValues = doc
.XPathSelectElements(@"//fields/field/value[last()]")
.Select(e => e.Value)
.ToList();
示例fiddle。