C# C语言中的复杂XML解析#

C# C语言中的复杂XML解析#,c#,xml,xsd2code,C#,Xml,Xsd2code,我需要解析一个复杂且大(100MB+)的XML文件。幸运的是,我有XML模式定义,但不幸的是,我不能使用xsd2code生成自动的XML反序列化,因为在XML的顶层使用了抽象消息类型。 XML文件的结构如下所示: <Head> <Batch> <Dog></Dog> <Dog></Dog> </Batch> </Head>

我需要解析一个复杂且大(100MB+)的XML文件。幸运的是,我有XML模式定义,但不幸的是,我不能使用xsd2code生成自动的XML反序列化,因为在XML的顶层使用了抽象消息类型。 XML文件的结构如下所示:

<Head>  
    <Batch>   
        <Dog></Dog>   
        <Dog></Dog>  
    </Batch>  
</Head>

xsd将批处理定义为包含抽象动物,而不是狗。Xsd2Code可以使用正确的XML属性创建Dog类,但Dog类位于另一个xsd文件中。 我试图将所有xsd粘贴在一起,但这无助于修复此问题。
有没有像LINQtoXML或Xpath这样的好方法来批量循环元素并创建Dog实例,而不需要手动解析Dog

有没有像LINQtoXML或Xpath这样的好方法来批量循环元素并创建Dog实例,而不需要手动解析Dog

这取决于你所说的“手动”是什么意思。我发现有一个模式很有用,其中每个相关的类都有一个静态的
FromXElement
工厂方法(或者一个构造函数采用
XElement
)来提取相关的细节。使用LINQ到XML,这非常简单,例如

public static Dog FromXElement(XElement element)
{
    // Or whatever...
    return new Dog((string) element.Element("Name"),
                   (double) element.Element("Weight"));
}
然后您可以使用:

List<Dog> dogs = batch.Elements("Dog")
                      .Select(x => Dog.FromXElement(x))
                      .ToList();

我不太明白你的问题。在XML中除了
之外,还会有其他标记吗?我知道您不想解析
标记的内部内容,但希望将其直接反序列化为
狗的实例,对吗?XML中可能还有其他动物。现在我只想读所有的狗。从xsd我可以生成dog类,但到目前为止我还不知道解析它的一般方法。。。为此..您只需创建一个字符串“”,这是正确的方式..现在转换或另存为.xml扩展名…那么,您什么时候使用它应该是xml格式,我不这么认为,传递它将是一个问题…正如之前所述,xml文件需要解析/反序列化,而不是序列化/创建。@weismat仅供澄清,您是否有与xml具有相同模式的类
Dog
?如果是这样,您可以在
dog
Cat
或任何类的构造函数中传递
XElement
,然后使用反射来分配属性。但是这将有很大的开销。所描述的工厂方法就是我手动调用的方法。我想知道是否能够自动创建Dog类(因为Dog本身也相当复杂,并且Dog在代码生成后包含XML属性)。例如,如果有一种简单的方法将大型XML文件的子树提取到一个新的XML文档中,它可能会起作用。@weismat:可能有,但就我个人而言,我对这种方法一直不太满意。我通常发现,让生成器执行我想要的操作比手动执行要花费更长的时间。请记住,LINQtoXML使“手动”版本比以前的版本简单得多。以上就是我要做的,但是当然,YMMV。Just Dog包含三个子结构。仅第一个结构就有大约20个属性。它更多的是编写易于维护的代码,而不是现在实际需要的以这种方式工作。@weismat:所以
Dog
工厂方法只需在其他三个方法中的每一个上调用
FromXElement
。。。你最终会得到很多代码,但这些代码非常简单。但是,如果在一个单独的XSD文件中有“dog”,那么如果您只是在该文件上尝试xsd2code,然后适当地调用生成的代码,会发生什么呢?我现在尝试了所有不同的方法来更改原始XML,但我现在可能会放弃,编写建议的工厂方法,因为我无法实现自动反序列化。
private static readonly Dictionary<string, Func<XElement, Animal>> Factories =
    new Dictionary<string, Func<XElement, Animal>>
{
    { "Dog", Dog.FromXElement },
    { "Cat", Cat.FromXElement },
    // etc
}
...
List<Animal> animals = batch.Elements()
                            .Select(x => Factories[x.Name.LocalName](x))
                            .ToList();