创建 C# 模型以反序列化 XML 个提要

Creating C# models to deserialize XML feeds

我正在构建一个 .net5 应用程序来抓取 RSS 提要,我想避免自定义字符串解析逻辑。相反,我想直接序列化 c# 对象中的 XML 。我以前做过一次,我使用 xsd.exe 生成模式文件,然后从中生成 .cs 文件。但是这次不起作用。这是我要抓取的内容

<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        <item>
            <title>Fire kills four newborn babies at children's hospital in India</title>
            <link>http://news.sky.com/story/india-fire-kills-four-newborn-babies-at-childrens-hospital-in-madhya-pradesh-12464344</link>
            <description>Four newborn babies have died after a fire broke out at a children's hospital in India, officials said.</description>
            <pubDate>Tue, 09 Nov 2021 07:51:00 +0000</pubDate>
            <guid>http://news.sky.com/story/india-fire-kills-four-newborn-babies-at-childrens-hospital-in-madhya-pradesh-12464344</guid>
            <enclosure url="https://e3.365dm.com/21/11/70x70/skynews-india-fire-childrens-hospital_5577072.jpg?20211109081515" length="0" type="image/jpeg" />
            <media:description type="html">A man carries a child out from the Kamla Nehru Children’s Hospital after a fire in the newborn care unit of the hospital killed four infants, in Bhopal, India, Monday, Nov. 8, 2021. There were 40 children in total in the unit, out of which 36 have been rescued, said Medical Education Minister Vishwas Sarang. (AP Photo) </media:description>
            <media:thumbnail url="https://e3.365dm.com/21/11/70x70/skynews-india-fire-childrens-hospital_5577072.jpg?20211109081515" width="70" height="70" />
            <media:content type="image/jpeg" url="https://e3.365dm.com/21/11/70x70/skynews-india-fire-childrens-hospital_5577072.jpg?20211109081515" />
            ...
        </item>
    </channel>
</rss>

到目前为止,我已经尝试使用 xsd.exe 和这个在线工具:https://xmltocsharp.azurewebsites.net/。两者都遇到了 <description><media:description> 标签的问题 - 它试图在 item 中创建第二个“描述”元素,但失败了:

  1. xsd.exe 执行失败并且不会生成 类 除非我删除其中一个。
  2. 在线工具生成 类,但是当我尝试使用它们实例化 XmlSerializer 时,它们失败了

我可以看到有两个 description 标签,但其中一个是在媒体名称空间中定义的。就 xsd 和 .net 而言,这些标签应该映射到相同的 属性,这显然是一个问题。这是无效的 XML 还是这些工具存在某种限制,无法成功映射。除了字符串解析之外还有其他解决方法吗?

问题是您必须向 xsd.exe 提供“媒体”架构定义。 Media RSS Specification 是“media”命名空间的完整描述。不幸的是,我找不到任何 XSD 文件,但可以从您提供的 XML 生成一个文件。我正在为此使用 Visual Studio,可能还有其他工具可以做到这一点(在 Visual Studio、select 中打开文件,来自菜单“XML”-“创建模式”) . Visual Studio 可能不会生成完整的模式,如规范中所述,而只会生成它可以在 XML 中检测到的内容。获得 XSD 文件后,您必须创建“媒体”模式文件。这是我能够从您的示例中生成的内容:

文件rss.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:import namespace="http://search.yahoo.com/mrss/" schemaLocation="media.xsd" />
    <xs:element name="rss">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="channel">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="item">
                                <xs:complexType mixed="true">
                                    <xs:sequence>
                                        <xs:element name="title" type="xs:string" />
                                        <xs:element name="link" type="xs:string" />
                                        <xs:element name="description" type="xs:string" />
                                        <xs:element name="pubDate" type="xs:string" />
                                        <xs:element name="guid" type="xs:string" />
                                        <xs:element name="enclosure">
                                            <xs:complexType>
                                                <xs:attribute name="url" type="xs:string" use="required" />
                                                <xs:attribute name="length" type="xs:unsignedByte" use="required" />
                                                <xs:attribute name="type" type="xs:string" use="required" />
                                            </xs:complexType>
                                        </xs:element>
                                        <xs:element ref="media:description" />
                                        <xs:element ref="media:thumbnail" />
                                        <xs:element ref="media:content" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="version" type="xs:decimal" use="required" />
        </xs:complexType>
    </xs:element>
</xs:schema>

文件media.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://search.yahoo.com/mrss/"> 
    <xs:element name="description">
        <xs:complexType>
            <xs:simpleContent>
                <xs:extension base="xs:string">
                    <xs:attribute name="type" type="xs:string" use="required" />
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
    </xs:element>
    <xs:element name="thumbnail">
        <xs:complexType>
            <xs:attribute name="url" type="xs:string" use="required" />
            <xs:attribute name="width" type="xs:unsignedByte" use="required" />
            <xs:attribute name="height" type="xs:unsignedByte" use="required" />
        </xs:complexType>
    </xs:element>
    <xs:element name="content">
        <xs:complexType>
            <xs:attribute name="type" type="xs:string" use="required" />
            <xs:attribute name="url" type="xs:string" use="required" />
        </xs:complexType>
    </xs:element>
</xs:schema>

如果需要,您可以扩展 XSD 文件 - 完整规范在上面的 link 中。现在调用 xsd.exe

c:\temp>xsd.exe media.xsd rss.xsd /c

将生成 c# class。