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

C# 如何遍历XDocument,逐个对象地获得完整的XML结构?,c#,linq-to-xml,C#,Linq To Xml,我有一个XmlDocument,我可以使用XmlNode遍历它,或者将其转换为XDocument并通过LINQ遍历它 <Dataset> <Person> <PayrollNumber>1234567</PayrollNumber> <Surname>Smith-Rodrigez</Surname> <Name>John-Jaime-Winston Juni

我有一个
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>
这会给我2个人记录(正确),每个记录都是一个字符串化的完整XML文档,格式为XML文档。只是上述XML文档的一个子集

但是现在如何将记录拆分为单独的节点或字段呢?最好是尽可能轻松地拆分

选项2:

foreach (XObject o in xDoc.Descendants("Person"))
{
    Console.WriteLine("Name" + o);
    // [...]
}
foreach (XElement element in xDoc.Descendants("Person"))
{
    // [...]
}
这将在一个字符串中获取每个人的XML节点(仅值),例如

1234567史密斯罗德里格斯约翰·詹姆·温斯顿青年5楼,城市中心2号楼,121国王威廉街北阿德莱德5000ICPR08 88888041 888999111111curly@stooge.comE

再说一次,没有多大用处

问题2
我可以很容易地验证
XDocument
,MSDN上有一些很好的示例,但我想知道如何标记错误的记录。理想情况下,我希望能够动态地将好记录过滤到新的
XDocument
,而将旧记录抛在脑后。这可能吗?

问题是您只是将元素打印为字符串。您需要编写代码来将
XElement
转换为业务对象。诚然,我希望将完整的XML写出来—您确定没有打印出
XElement.Value
(连接所有子体文本节点)吗


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

为什么不使用XML反序列化

有两种方法可以做到这一点

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

  • 第二种方法是将给定的XML转换为与
    Person
    对象的默认序列化相匹配的XML,然后进行反序列化


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

抱歉-是的,我使用的是Xelement.value-至少对于第二个示例来说是这样的。(现在已经很晚了,我很累)。问题是,我不想连接后代值-我需要单独组织它们,但我确实希望一开始就选择它们,这样我就可以轻松地将它们作为单个对象组织起来。然后将它们组织起来并进一步拆分,但我似乎无法在此级别进行枚举。我使用的是:foreach(xDoc.subscriptions(“Person”)中的XElement元素){Console.WriteLn(element.value);}}这给了我一个连接的字符串。@MtTumbledown:是的,可以。不要使用Value属性-单独询问子元素。访问XElement上的Value属性将连接后代文本节点,这就是它要做的。当然-我想没有快速的方法来做-在XElement中有一个硬移植元素询问每个子元素-可能是通过节点id。我希望会有一些3.5 LINQ支持,可以自动用子元素填充结构。谢谢!我可以这样做。它为我提供了一个非常有用的列表,其中包含每个节点的描述,后跟它的值:IEnumerable nodeList=element.DegenantNodes();foreach(nodeList中的XNode xn){Console.WriteLine(“名称:+xn”);}