如何将大型 xml 文件的一部分反序列化为 C# 类?

2024-03-11

我已经阅读了一些关于如何反序列化 xml 的帖子和文章,但仍然没有弄清楚应该如何编写代码来满足我的需求,所以..我为另一个关于反序列化 xml 的问题道歉))

我有一个大(50 MB)的 xml 文件,需要反序列化。我使用 xsd.exe 获取文档的 xsd 架构,然后自动生成放入项目中的 C# 类文件。我想从这个 xml 文件中获取一些(不是全部)数据并将其放入我的 sql 数据库中。

这是文件的层次结构(简化,xsd 非常大):

public class yml_catalog 
{
    public yml_catalogShop[] shop { /*realization*/ }
}

public class yml_catalogShop
{
    public yml_catalogShopOffersOffer[][] offers { /*realization*/ }
}

public class yml_catalogShopOffersOffer
{
    // here goes all the data (properties) I want to obtain ))
}

这是我的代码:

第一种方法:

yml_catalogShopOffersOffer catalog;
var serializer = new XmlSerializer(typeof(yml_catalogShopOffersOffer));
var reader = new StreamReader(@"C:\div_kid.xml");
catalog = (yml_catalogShopOffersOffer) serializer.Deserialize(reader);//exception occures
reader.Close();

我收到 InvalidOperationException: XML(3,2) 文档中存在错误

第二种方法:

XmlSerializer ser = new XmlSerializer(typeof(yml_catalogShopOffersOffer));
yml_catalogShopOffersOffer result;
using (XmlReader reader = XmlReader.Create(@"C:\div_kid.xml"))          
{
    result = (yml_catalogShopOffersOffer)ser.Deserialize(reader); // exception occures
}

InvalidOperationException:XML(0,0) 文档中存在错误

third: 我尝试反序列化整个文件:

 XmlSerializer ser = new XmlSerializer(typeof(yml_catalog)); // exception occures
 yml_catalog result;
 using (XmlReader reader = XmlReader.Create(@"C:\div_kid.xml"))          
 {
     result = (yml_catalog)ser.Deserialize(reader);
 }

我得到以下信息:

error CS0030: The convertion of type "yml_catalogShopOffersOffer[]" into "yml_catalogShopOffersOffer" is not possible.

error CS0029: The implicit convertion of type "yml_catalogShopOffersOffer" into "yml_catalogShopOffersOffer[]" is not possible.

那么,如何修复(或覆盖)代码以免出现异常?

edits: 当我写的时候也这样:

XDocument doc = XDocument.Parse(@"C:\div_kid.xml");

发生 XmlException:根级别、字符串 1、位置 1 上存在未经允许的数据。

这是 xml 文件的第一个字符串:

<?xml version="1.0" encoding="windows-1251"?>

edits 2:xml 文件简短示例:

<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE yml_catalog SYSTEM "shops.dtd">
<yml_catalog date="2012-11-01 23:29">
<shop>
   <name>OZON.ru</name>
   <company>?????? "???????????????? ??????????????"</company>
   <url>http://www.ozon.ru/</url>
   <currencies>
     <currency id="RUR" rate="1" />
   </currencies>
   <categories>
      <category id=""1126233>base category</category>
      <category id="1127479" parentId="1126233">bla bla bla</category>
      // here goes all the categories
   </categories>
   <offers>
      <offer>
         <price></price>
         <picture></picture>
      </offer>
      // other offers
   </offers>
</shop>
</yml_catalog>

P.S.我已经接受了答案(非常完美)。但现在我需要使用categoryId 找到每个Offer 的“基本类别”。数据是分层的,基本类别是没有“parentId”属性的类别。因此,我编写了一个递归方法来查找“基本类别”,但它永远不会完成。看起来算法不是很快))
这是我的代码:(在 main() 方法中)

var doc = XDocument.Load(@"C:\div_kid.xml");
var offers = doc.Descendants("shop").Elements("offers").Elements("offer");
foreach (var offer in offers.Take(2))
        {
            var category = GetCategory(categoryId, doc);
            // here goes other code
        }

辅助方法:

public static string GetCategory(int categoryId, XDocument document)
    {
        var tempId = categoryId;
            var categories = document.Descendants("shop").Elements("categories").Elements("category");
            foreach (var category in categories)
            {
                if (category.Attribute("id").ToString() == categoryId.ToString())
                {
                    if (category.Attributes().Count() == 1)
                    {
                        return category.ToString();
                    }
                    tempId = Convert.ToInt32(category.Attribute("parentId"));
                }
            }
        return GetCategory(tempId, document);
    }

在这种情况下我可以使用递归吗?如果没有,我还能如何找到“基本类别”?


尝试一下 LINQ to XML。XElement result = XElement.Load(@"C:\div_kid.xml");

LINQ 中的查询非常出色,但无可否认,一开始有点奇怪。您可以使用类似 SQL 的语法或使用 lambda 表达式从文档中选择节点。然后创建包含您感兴趣的数据的匿名对象(或使用现有的类)。

最好的办法是看到它的实际效果。

  • 表示命名空间的示例 http://code.msdn.microsoft.com/vstudio/LINQ-to-XML-XName-Samples-6ce5f9c3
  • msdn 上还有很多。搜索 LINQ to XML。

根据您的示例 XML 和代码,以下是一个具体示例:

var element = XElement.Load(@"C:\div_kid.xml");
var shopsQuery =
    from shop in element.Descendants("shop")
    select new
    {
        Name = (string) shop.Descendants("name").FirstOrDefault(),
        Company = (string) shop.Descendants("company").FirstOrDefault(),
        Categories = 
            from category in shop.Descendants("category")
            select new {
                Id = category.Attribute("id").Value,
                Parent = category.Attribute("parentId").Value,
                Name = category.Value
            },
        Offers =
            from offer in shop.Descendants("offer")
            select new { 
                Price = (string) offer.Descendants("price").FirstOrDefault(),
                Picture = (string) offer.Descendants("picture").FirstOrDefault()
            }

    };

foreach (var shop in shopsQuery){
    Console.WriteLine(shop.Name);
    Console.WriteLine(shop.Company);
    foreach (var category in shop.Categories)
    {
        Console.WriteLine(category.Name);
        Console.WriteLine(category.Id);
    }
    foreach (var offer in shop.Offers)
    {
        Console.WriteLine(offer.Price);
        Console.WriteLine(offer.Picture);
    }
}  

作为额外:以下是如何从平面反序列化类别树category元素。 您需要一个适当的类来容纳它们,因为 Children 列表必须有一个类型:

class Category
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public List<Category> Children { get; set; }
    public IEnumerable<Category> Descendants {
        get
        {
            return (from child in Children
                    select child.Descendants).SelectMany(x => x).
                    Concat(new Category[] { this });
        }
    }
}

要创建包含文档中所有不同类别的列表:

var categories = (from category in element.Descendants("category")
                    orderby int.Parse( category.Attribute("id").Value )
                    select new Category()
                    {
                        Id = int.Parse(category.Attribute("id").Value),
                        ParentId = category.Attribute("parentId") == null ?
                            null as int? : int.Parse(category.Attribute("parentId").Value),
                        Children = new List<Category>()
                    }).Distinct().ToList();

然后将它们组织成一棵树(大量借用平面列表到层次结构 https://stackoverflow.com/questions/4694227/flat-list-to-hierarchy):

var lookup = categories.ToLookup(cat => cat.ParentId);
foreach (var category in categories)
{
    category.Children = lookup[category.Id].ToList();
}
var rootCategories = lookup[null].ToList();

找到包含以下内容的根theCategory:

var root = (from cat in rootCategories
            where cat.Descendants.Contains(theCategory)
            select cat).FirstOrDefault();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将大型 xml 文件的一部分反序列化为 C# 类? 的相关文章

  • 我的 std::hash for std::tuples...有什么改进吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有些人可能已经注意到 std hash 不支持元组 所以我添加了一个重载 它看起来比我到目前为止看到的解决方案 更好 有人有进一步减少这段代码的
  • Visual Studios 2015 中的“恢复 NuGet 包”没有执行任何操作

    我将解决方案从 SVN 拉入 Visual Studios 2015 代码中的一些 使用 引用出现错误 因此我尝试在右键单击 解决方案 中的解决方案时运行 恢复 NuGet 包 选项探索者 这没有任何作用 我必须手动进入 nuget 管理器
  • 在 WCF 上重用我的 PagedList 对象

    问题 我有一个自定义集合PagedList
  • Boost MPI 在监听列表时不会释放资源?

    这是一个后续问题如何释放 boost mpi request https stackoverflow com questions 44078901 how do i free a boostmpirequest 我在监听列表而不是单个项目时
  • Qt/c++ 随机字符串生成[重复]

    这个问题在这里已经有答案了 我正在创建一个应用程序 需要生成多个随机字符串 几乎就像一个由一定长度的 ASCII 字符组成的唯一 ID 这些字符混合有大写 小写 数字字符 有没有 Qt 库可以实现这一点 如果没有 在纯 C 中生成多个随机字
  • 对 ExecuteNonQuery() 的单次调用是原子的

    对 ExecuteNonQuery 的单次调用是否是原子的 或者如果单个 DbCommand 中有多个 sql 语句 那么使用事务是否有意义 请参阅我的示例以进行说明 using var ts new TransactionScope us
  • 如何通过 libwebsocket 发送异步数据?

    我正在将 Warmcat 的 libwebsocket C 库用于小型 Websocket 服务器 我已经启动并运行了这些示例 并且可以发送数据以响应从 websocket 接收数据 例如回显发送的反向字节 但是 我无法弄清楚如何在不使用
  • C++ 指针和对象实例化

    这有效 MyObject o o new MyObject 而这并不 MyObject o new MyObject Why 关键词new 返回一个指针 http msdn microsoft com en us library kewsb
  • 如何在 Visual Basic DLL 和 C++ DLL 之间创建隔离/免注册 COM?

    我必须在 C DLL 中使用 VB COM DLL 我弄清楚了如何从 C DLL 访问 VB COM DLL 并且它可以工作 现在我遇到了一个问题 我必须使用隔离的 COM 免注册 COM 因为我无法在必须使用它的每台 PC 上注册 DLL
  • 检查两个函数或成员函数指针的签名是否相等

    我编写了一些代码来检查自由函数的签名是否等于成员函数的签名等 它比较提取的返回类型和函数参数 include
  • 查找方法不适用于 EF6.1 模拟

    我已经使用这些 msdn 指南设置了模拟 使用模拟框架进行测试 EF6 及以上 http msdn microsoft com en us data dn314429 var bsAc db BusAcnts FirstOrDefault
  • 如果finally 块包含await,为什么*有时*不会在ThreadAbortException 上执行?

    UPDATE 我不认为这个问题是重复的ThreadAbortException最后可以跳过吗 https stackoverflow com questions 18002668 can threadabortexception skip
  • linq where 子句和 count 导致 null 异常

    除非 p School SchoolName 结果为 null 否则下面的代码将起作用 在这种情况下 它会导致 NullReferenceException if ExistingUsers Where p gt p StudentID i
  • 从 C# 调用时无法识别 Powershell 命令

    这是这个的延续Question https stackoverflow com questions 66280000 powershell object returns null 66280138 noredirect 1 comment1
  • 膨胀类 android.support.design.internal.BottomNavigationView 时出错

    我正在制作我的第一个应用程序 这是一个简单的应用程序 带有启动屏幕和主要活动 现在我有两个构建变体 免费版本 活动底部有 Admob 横幅 付费版本 该应用程序不会在底部显示 admob 横幅 而是将其替换为用于切换活动的底部导航视图 我将
  • 在特定线程上运行工作

    我想要一个特定的线程 任务队列并在该单独的线程中处理任务 应用程序将根据用户的使用情况创建任务并将其排队到任务队列中 然后单独的线程处理任务 即使队列为空 保持线程活动并使用它来处理排队任务也至关重要 我尝试过几种实现TaskSchedul
  • 实体框架读取列但阻止其更新

    给定一个数据库表 其中有一列包含历史数据但不再填充 实体框架中是否有一种方法可以读取该列 但在使用相同的模型对象时防止它被更新 例如我有一个对象 public class MyObject public string CurrentData
  • 'iter' 的名称查找已更改为新的 ISO 'for' 范围

    我正在尝试编译下面的两个文件 但从编译器收到错误消息 gcc 4 3 3 Linux 错误位于带有以下符号的行 LINE WITH ERROR 我做错了什么 我该怎么改变 路易斯 g c b h b cpp b cpp In functio
  • 如何在控制台程序中获取鼠标位置?

    如何在 Windows 控制台程序中用 C 获取鼠标单击位置 点击时返回鼠标位置的变量 我想用简单的文本命令绘制一个菜单 这样当有人点击时 游戏就会注册它并知道位置 我知道如何做我需要做的一切 除了单击时获取鼠标位置 您需要使用 Conso
  • 如何根据当前日期时间发现财政年度?

    我需要基于当前或今天的日期时间的财政年度 假设我们认为今天的日期是10 April 2011 那么我需要输出为Financial Year 2012在某些情况下 我需要以短格式显示相同的输出FY12 我想以两种方式显示 在我们的要求中 考虑

随机推荐

  • 是否可以在 NFC 卡中实现令牌队列?

    这个问题专门针对 MIFARE Ultralight C EV1 或 MIFARE DESFire EV1 甚至 NTAG 卡 我想实现一个令牌系统 以便每次普通用户读取其中一张卡时 他们都会获得一个可用令牌 该令牌将从他们正在读取的 NF
  • Rails 3 activerecord order - 正确的sql注入工作是什么?

    假设我有一个用户列表页面 您可以按不同的列进行排序 当单击 电子邮件 时 它将传递 sort by 电子邮件 排序方向 asc 或 desc sort by email really params sort by sort directio
  • FFMPEG Android 库增加大小

    我在我的项目中使用 ffmpeg 库 问题是应用程序 apk 大小太大 有人知道如何减小 apk 大小吗 任何帮助 建议或链接将不胜感激 谢谢 你好 tech android 和 gulab patel 我已经找到了解决方案 Android
  • 从开发工具中的检查元素查找原始源文件路径

    我正在尝试为使用 React 和 Webpack 构建的大型 Web 应用程序添加可访问性 这需要从应用程序返回源文件 有没有办法查看代码最初来自哪个文件 检查元素和查看源代码很好 但我找不到生成代码的源文件的路径 有没有办法在开发工具 c
  • 即使使用限制,Rails Mongoid 模型查询结果也会返回错误的大小/长度/计数信息

    当在我的 Rails 应用程序中查询某个模型时 它返回正确的结果 摘录size length or count信息 甚至使用limit标准 recipes Recipe where bitly url gt some url order b
  • 访问控制允许来源-本地主机

    我在通过ajax接收json时遇到问题 错误如下 根据我迄今为止发现的有关该错误的信息 这似乎是某种跨域问题 但我不知道这意味着什么以及如何解决它 响应头可能有问题 我自己创建了 API 之前没有经验 但是如果直接在浏览器中访问 url 则
  • 如何使用 PowerShell 命令从 terraform Variables.tf 文件中提取变量值

    我有一个变量 tf 文件 其中包含所有项目变量 我尝试使用 PowerShell 获取变量值 变量 tf variable products default Product 1 Product 2 Product 3 Product 4 v
  • 忽略和有什么缺点

    不使用有什么缺点吗 and 在用 HTML 和 PHP 编写的网页上 我的意思是 无论有没有它 一切都可以正常工作 那么为什么要使用它呢 它们在规范中是明确可选的 因此文档仍然有效 自从原始规格 https www w3 org MarkU
  • 拒绝在框架中显示“url”,因为它将“X-Frame-Options”设置为“sameorigin”。 JavaScript 代码有问题

    我正在开发一个网站 当您搜索该网站时 该网站会隐藏您的历史记录 function code url var win window open win document body style margin 0 win document body
  • Java Dom 解析器报告子节点数量错误

    我有以下 xml 文件
  • 如何在 capnproto C++ 生成的代码中设置列表的字符串项?

    我有这样的 capnproto 定义 struct School name 0 Text address 1 Address foundation 2 Date emailAddresses 3 List Text 我想在构建器中使用与此类
  • JSLint:在定义错误之前使用函数

    我使用 JSLint 来验证我的大部分外部 Javascript 文件 但我得到的最大数量的错误来自于定义之前使用的函数 这真的是我应该担心的问题吗 看来 Firefox IE7 和 Chrome 并不关心 功能与流行的一样init 我经常
  • 时间延迟 Tkinter

    我想在 PyDev Eclipse python 2 75 中制作一个图形窗口 我做了一些事情 但我想做一个 入口 眨眼 它测试用户输入 如果它是一个整数 它应该闪烁绿色一秒钟 然后变成白色 但如果它是一串其他东西 它应该闪烁红色 然后变成
  • 如何制作分割文本输入占位符?

    我想要做的事情也许最好用图像来解释 我将在下面添加 但本质上它是文本inputHTML 字段一半是预先存在的值 另一半是可替换的 我尝试添加两个value and a placeholder场 然后通过将它们分开padding left在
  • python SyntaxError 与 dict(1=...), 但 {1:...} 有效

    Python 似乎在接受字典类型的键方面不一致 或者 换句话说 它允许以一种定义字典的方式使用某些类型的键 但不允许以其他方式使用 gt gt gt d 1 one 2 2 gt gt gt d 1 one gt gt gt e dict
  • UIHostingController 是否必须位于视图控制器层次结构中?

    我想在我的基于 UIKit 的 UI 中嵌入一些 SwiftUI 不幸的是 Apple 不提供UIHostingView only UIHostingController 我可以或多或少地忽略该控制器并只使用它的视图 还是我真的需要将它添加
  • Clojure 中 definterface 和 defprotocol 的区别

    除了缺少文档之外 还有什么区别definterface and defprotocol在 Clojure 中 根据Clojure 的乐趣 使用的优点definterface over defprotocol受到限制 完全是因为前者允许原始类
  • 在 Libgdx 中使用屏幕时重用代码

    根据我在阅读其他人关于如何制作不同屏幕的代码时的理解 您执行一个主处理程序类 然后为每个屏幕创建一个新类 让我困惑的是 每当你创建一个新屏幕时 你都必须重新定义将要渲染的所有内容 例如 SpriteBatch 精灵 字体等 有没有办法在所有
  • Scala:包导入冲突

    我正在导入一个隐式 scala concurrent ExecutionContext Implicits global 在此之前 我import global Analytics xyzMethod 其中 global 是我的包中的一个目
  • 如何将大型 xml 文件的一部分反序列化为 C# 类?

    我已经阅读了一些关于如何反序列化 xml 的帖子和文章 但仍然没有弄清楚应该如何编写代码来满足我的需求 所以 我为另一个关于反序列化 xml 的问题道歉 我有一个大 50 MB 的 xml 文件 需要反序列化 我使用 xsd exe 获取文