如何遍历XDocument,逐个对象地获取完整的XML结构?

时间:2010-01-11 13:10:38

标签: c# linq-to-xml

我有XmlDocument我可以使用XmlNode遍历或将其转换为XDocument并通过LINQ遍历它。

<Dataset>
    <Person>
        <PayrollNumber>1234567</PayrollNumber>
        <Surname>Smith-Rodrigez</Surname>
        <Name>John-Jaime-Winston Junior</Name>
        <Skills>
            <Skill>ICP</Skill>
            <Skill>R</Skill>
        </Skills>
        <HomePhone>08 8888 8888</HomePhone> 
        <MobilePhone>041 888 999</MobilePhone>
        <Email>curly@stooge.com</Email>
    </Person>
    <Person>
        <PayrollNumber>12342567</PayrollNumber>
        <Surname>Smith-Rodrigez</Surname>
        <Name>Steve</Name>
        <Skills>
            <Skill>Resus</Skill>
            <Skill>Air</Skill>
        </Skills>
        <HomePhone>08 8888 8888</HomePhone> 
        <MobilePhone>041 888 999</MobilePhone>
        <Email>curly@stooge.com</Email>
    </Person>
</Dataset>

问题1

我想将XML中的Person记录/节点转换为业务实体对象(PO​​CO)。 因此,我必须一次迭代一个Person节点,然后解析各个值。最后一点本身很有趣,但首先我必须得到实际的人物记录。我遇到的问题是,如果我按个别节点选择(在XmlList中使用XmlDocoment)。

我最终按名称聚合所有字段。我担心这样做是因为其中一个人节点不完整,甚至丢失,然后当我通过并将字段聚合到业务对象时,我不知道哪个丢失了。我会尝试验证 - 见问题2。

我意识到这可以通过反思完成,但我很感兴趣。

我尝试通过Person对象迭代:

选项1:

foreach (XObject o in xDoc.Descendants("Person"))
{
    Console.WriteLine("Name" + o);
    // [...]
}

这让我得到2个人的记录(正确),每个记录都是一个字符串化的完整XML文档 - 格式化为XML文档。只是上述XML文档的一部分。

但是如何将记录现在拆分为单独的节点或字段 - 最好尽可能无痛?

选项2:

foreach (XElement element in xDoc.Descendants("Person"))
{
    // [...]
}

这为我提供了XML节点 - 仅限于值 - 每个人都在一个字符串中,例如

  

1234567Smith-RodrigezJohn-Jaime-Winston JuniorLevel 5,City Central Tower 2,121 King William StNorth Adelaide 5000ICPR08 8888 8888041 888 999111111curly@stooge.comE

同样,没什么用。

问题2

我可以很容易地验证XDocument,MSDN上有一些很好的例子,但我想知道如何标记错误的记录。理想情况下,我希望能够将好的记录过滤到新的XDocument,而不是旧的记录。这可能吗?

2 个答案:

答案 0 :(得分:4)

问题在于您只是将元素打印为字符串。您需要编写代码以将XElement <Person>转换为业务对象。不可否认,我希望期望写出完整的XML - 你确定你没有打印出XElement.Value(连接所有后代文本节点)吗?

(我不确定你的第二个问题的答案 - 我建议你在这里将它作为一个单独的问题,这样我们就不会在一个页面中得到答案的混合。)

答案 1 :(得分:1)

为什么不使用XML反序列化?

有两种方法可以做到。

  • 第一个是通过向Person类及其属性添加适当的属性来修改业务对象Person以匹配给定的XML 。 XML非常简单,因此如果对象属性和XML节点之间没有1:1匹配,则可能只需要更改名称。例如,您必须为[XmlArray("Skills")]集合指定[XmlArrayItem("Skill)]Skills

  • 第二个是将给定的XML转换为与Person对象的默认序列化匹配的XML,然后反序列化。

第二种解决方案还可以让您轻松过滤“坏”记录。