我有一个像这样的嵌套xml。
< H>
< FP >
< Name="FP1"/>
< R >
< Name = "R1"/>
< O>
< Name="O1"/>
< /O>
< O>
< Name="O2"/>
< /O>
< /R>
< R>
< Name = "R2"/>
< O>
< Name="O4"/>
< /O>
< /R>
< /FP>
< FP>
< Name="FP2" />
< R>
< Name = "R3"/>
< O>
< Name="O5"/>
< /O>
< O>
< Name="O6"/>
< /O>
< /R>
< /FP>
< R>
< Name="R4"/>
< O>
< Name="O7"/>
< /O>
< O>
< Name="O8"/>
< /O>
< /R>
< R>
< Name="R5"/>
< O >
< Name="O9"/>
< /O>
< /R>
< /H>
我正在使用反序列化来读取这个xml。
这是我的反序列化类:
[XmlRoot("H")]
public class ReplyH
{
[XmlElement("FP")]
public List<ReplyFP> FPs;
[XmlElement("R")]
public List<ReplyR> Rs;
}
public class ReplyFP
{
[XmlElement("Name")]
public string Name;
[XmlElement("R")]
public List<ReplyR> Rs = new List<ReplyR>();
}
public class ReplyR
{
[XmlElement("Name")]
public string Name;
[XmlElement("O")]
public List<ReplyO> Os = new List<ReplyO>();
}
public class ReplyO
{
[XmlElement("Name")]
public string Name;
}
我需要迭代O标签。
类似于foreach(H.FP.R.O中的var O)和foreach(H.R.O中的var O)
1)。我需要找到上面示例中的最后一个<O>
标记
&LT; O&GT; &LT;名称=“O9”/&gt; &LT; / O&GT; .
2). I also need to get the parent
环R Name and
{FP {1}} O`
如何使用linq / lambda表达式获取此信息?
由于
答案 0 :(得分:1)
以下是使用Xml.Linq:更新另请参阅competing answer for updated question
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using System;
public class stuff
{
public static void Main(string[] args)
{
var doc = XDocument.Parse(xml);
var last = doc.Root
.XPathSelectElements("//H/FP/R/O | //H/R/O")
.Last();
Console.WriteLine(last);
Console.WriteLine("Parent R has name '{0}'", last.Parent.Attribute("Name").Value);
var granddad = last.Parent.Parent;
if (granddad.Name == "FP")
Console.WriteLine("Parent FP has name '{0}'", granddad.Attribute("Name").Value);
}
const string xml = @"<H>
<FP Name=""FP1"">
<R Name=""R1"">
<O Name=""O1""/>
<O Name=""O2""/>
</R>
<R Name=""R2"">
<O Name=""O4""/>
</R>
</FP>
<FP Name=""FP2"">
<R Name=""R3"">
<O Name=""O5""/>
<O Name=""O6""/>
</R>
</FP>
<!--
<R Name=""R4"">
<O Name=""O7""/>
<O Name=""O8""/>
</R>
<R Name=""R5"">
<O Name=""O9""/>
</R>
-->
</H>";
}
输出
<O Name="O6" />
Parent R has name 'R3'
Parent FP has name 'FP2'
如果取消注释XML的最后一部分:
<!--
<R Name=""R4"">
<O Name=""O7""/>
<O Name=""O8""/>
</R>
<R Name=""R5"">
<O Name=""O9""/>
</R>
-->
输出变为:
<O Name="O9" />
Parent R has name 'R5'
答案 1 :(得分:1)
对于更新的问题,使用Linq-to-objects更新答案。
代码不如Linq-to-XML falvour优雅,但它可以工作。
备注强>
- 因为FPs和Rs位于顶层的不同集合中,所以没有办法知道他们的文档排序,就像在源XML中一样。我假设Rs遵循
ReplyH
内的FP,就像代码所示(并且样本XML似乎也暗示)。- 醇>
我必须修复序列化类才能使用
[XmlAttribute("Name")] public string Name;
在哪里(意外?)在您的问题中说
XmlElement("Name")
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Linq;
using System.IO;
using System;
public class Program
{
public static void Main(string[] args)
{
ReplyH doc;
using (var reader = new StringReader(xml))
doc = (ReplyH) new XmlSerializer(typeof(ReplyH)).Deserialize(reader);
var Rs = doc.FPs
.SelectMany(fp => fp.Rs.Select(r => new { Parent = fp , R=r }))
.Concat ( doc.Rs.Select(r => new { Parent = (ReplyFP) null, R=r }));
var Os = Rs.SelectMany(r => r.R.Os.Select(o => new { Parent = r, O=o }));
var lastO = Os.Last();
Console.WriteLine(lastO.O.Name);
if (lastO != null)
{
Console.WriteLine("Parent R has name '{0}'", lastO.Parent.R.Name);
ReplyFP granddad = lastO.Parent.Parent;
if (granddad != null)
Console.WriteLine("Parent FP has name '{0}'", granddad.Name);
}
}
const string xml = @"<H>
<FP Name=""FP1"">
<R Name=""R1"">
<O Name=""O1""/>
<O Name=""O2""/>
</R>
<R Name=""R2"">
<O Name=""O4""/>
</R>
</FP>
<FP Name=""FP2"">
<R Name=""R3"">
<O Name=""O5""/>
<O Name=""O6""/>
</R>
</FP>
<!--
<R Name=""R4"">
<O Name=""O7""/>
<O Name=""O8""/>
</R>
<R Name=""R5"">
<O Name=""O9""/>
</R>
-->
</H>";
}
[XmlRoot("H")] public class ReplyH {
[XmlElement("FP")] public List<ReplyFP> FPs = new List<ReplyFP>();
[XmlElement("R")] public List<ReplyR> Rs = new List<ReplyR>();
}
public class ReplyFP {
[XmlAttribute("Name")] public string Name;
[XmlElement("R")] public List<ReplyR> Rs = new List<ReplyR>();
}
public class ReplyR {
[XmlAttribute("Name")] public string Name;
[XmlElement("O")] public List<ReplyO> Os = new List<ReplyO>();
}
public class ReplyO {
[XmlAttribute("Name")] public string Name;
}
输出:
O6
Parent R has name 'R3'
Parent FP has name 'FP2'
或者在取消评论最后一个XML块之后:
O9
Parent R has name 'R5'