没有标准架构时,读取xml文件的最佳方法是什么?

时间:2011-11-28 06:52:31

标签: c# xml-serialization linq-to-xml

我正在开发一个应用程序,其中,我必须读取每次都有不同节点集的XML文件,尽管在所有文件中只显示一定数量的节点,它们出现的组合一直在变化,XML文件是由另一个我无法控制的系统生成的,我正在研究Linq到XML和XML序列化,但我想序列化不是一个选择,因为它需要预先构建的类来创建对象。

示例XML数据

<Employee>
  <PersonalInfo>
    <FirstName>Vamsi</FirstName>
    <LastName>Krishna</LastName>
  </PersonalInfo>
  <EmploymentInfo>
    <Department>
      <Id>101</Id>
      <Position>SD</Position>
    <Department>
  <EmploymentInfo>
</Employee>

另一种格式

<Employee>
  <PersonalInfo>
    <FirstName>Vamsi</FirstName>
    <LastName>Krishna</LastName>
  </PersonalInfo>      
</Employee>

您可以在第二个示例中观察到EmploymentInfo节点完全丢失,有许多组合可以将XML数据呈现给应用程序,我必须读取XML文件验证它插入到一个SQL Server数据库通过我的C#代码。

2 个答案:

答案 0 :(得分:1)

您可以编写一个使用.Net Xpath implementation的解析器类。在处理数据之前,解析器应测试特定节点的子元素。

访问MSDN了解完整语法。

<强>更新

我将采取哪些措施来解决问题。首先,一些Model类来保存一些数据:

public class PersonalInfo 
{
   public string FirstName { get; set;}
   public string LastName { get; set;}
   // more properties
}

public class EmployeeModel 
{
    // remove List<> if you always just have 1 personalinfo child element
    public List<PersonalInfo> {get; set;}   
    public List<EmploymentInfo> {get; set;}
    // more properties
}

现在你的“Parser”:

public class MyParser
{
    // load xml string or xml file in constructor
    public MyParser(string xmlSource) { .. }


    public EmployeeModel GetEmployeeModel()
    {
         var result = new EmployeeModel();
         // use what ever you want to select nodes from your xml
         // and set data of result

         return result;
    }
}

在生产代码中,您可以使用此解析器类来获取xml数据的模型。

答案 1 :(得分:1)

我说这取决于。

如果您只想以强类型方式与另一个系统进行通信,并且您可以期望XML模式不会经常更改,那么您可能对XML序列化没有问题。只需将反序列化封装到一个单独的组件中并编写它们的不同版本(是的,您需要能够确定当前使用的模式版本)。我的意思是,每个版本都有自己的一组类,这些类是序列化程序所针对的。

但是,如果您真的无法从外部应用程序使用的模式中推断出系统并需要一些智能解析器,那么最好使用XPath或Linq到XML或其他一些XML级API来手动处理XML-s

顺便说一下,XMLSerializer的两个样本都非常简单。在第二种情况下,它只会将EmploymentInfo设置为null。