【问题标题】:Custom xsd file to C# classes deserialization on runtime自定义 xsd 文件到 C# 类在运行时反序列化
【发布时间】:2011-12-26 12:32:52
【问题描述】:

我正在尝试将 xsd 文件转换为 .net 类。 我为这个主题搜索了很多,发现xsd.exe是实现它的方法之一,但我仍然有两个顾虑

  1. 我不想从命令提示符手动生成类,但希望所有这些都在运行时完成。为此,我尝试使用 System.Diagnostics.Process 在运行时运行 xsd.exe,但未能成功,并且在进程启动时出现闪烁的命令提示符窗口。

  2. 我什至没有成功获取从命令提示符生成的类。它给了我错误“无法验证架构 D:\Response.xsd。”

所以基本上我正在尝试实现一些将使用我的 xsd 字符串并在运行时将其反序列化为我的类类型之一的东西,就像我们使用 XmlSerializer 类处理 Xml 字符串一样。

我想提一下,我认为我的 xsd 字符串不是一般的 xsd 类型,而是一种自定义,其中一个响应的示例是这样的

<?xml version="1.0" encoding="iso-8859-1"?>
<serv:message xmlns:serv="http://www.webex.com/schemas/2002/06/service"
xmlns:com="http://www.webex.com/schemas/2002/06/common"
xmlns:use="http://www.webex.com/schemas/2002/06/service/user">
    <serv:header>
        <serv:response>
            <serv:result>SUCCESS</serv:result>
            <serv:gsbStatus>BACKUP</serv:gsbStatus>
        </serv:response>
    </serv:header>
    <serv:body>
        <serv:bodyContent xsi:type="use:getLoginTicketResponse"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <use:ticket>5e9733eb9efeb02d80aa0551ef7e9ccd</use:ticket>
            <use:apiVersion>WebEx XML API V3.9.0</use:apiVersion>
        </serv:bodyContent>
    </serv:body>
</serv:message>

编辑 - 我现在成功地为我的 xml 生成了类文件,就在这里

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.webex.com/schemas/2002/06/service/user")]
public partial class getLoginTicketResponse : bodyContentType
{

    private string ticketField;

    private string apiVersionField;

    /// <remarks/>
    public string ticket
    {
        get
        {
            return this.ticketField;
        }
        set
        {
            this.ticketField = value;
        }
    }

    /// <remarks/>
    public string apiVersion
    {
        get
        {
            return this.apiVersionField;
        }
        set
        {
            this.apiVersionField = value;
        }
    }
}

这是 bodyContentType

/// <remarks/>
[System.Xml.Serialization.XmlIncludeAttribute(typeof(getLoginTicketResponse))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.webex.com/schemas/2002/06/service")]
[System.Xml.Serialization.XmlRootAttribute("getLoginTicket", Namespace = "http://www.webex.com/schemas/2002/06/service/user", IsNullable = false)]
public partial class bodyContentType
{
}

现在,尝试像这样序列化它

var nameSpaceManager = new XmlNamespaceManager(responseXML.NameTable);
nameSpaceManager.AddNamespace("serv", "http://www.webex.com/schemas/2002/06/service");
nameSpaceManager.AddNamespace("com", "http://www.webex.com/schemas/2002/06/common");
nameSpaceManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
nameSpaceManager.AddNamespace("meet", "http://www.webex.com/schemas/2002/06/service/meeting");
nameSpaceManager.AddNamespace("att", "http://www.webex.com/schemas/2002/06/service/attendee");
nameSpaceManager.AddNamespace("use", "http://www.webex.com/schemas/2002/06/service/user");

XmlNode statusNode = responseXML.SelectSingleNode("/serv:message/serv:body", nameSpaceManager);
TextReader reader = new StringReader(s);
XmlSerializer serializer = new XmlSerializer(typeof(getLoginTicketResponse));

var obj = serializer.Deserialize(reader);

但不断出现错误 “XML 文档 (1, 2) 中存在错误。” 我尝试更改 xml 字符串中的许多内容,但无法成功

任何帮助将不胜感激!

【问题讨论】:

  • 这不是 XSD,这只是 xml 响应。
  • @rene 哎呀!好的。那么你能否给我一个例子来说明我如何为这个结构设计一个类。我没有得到这个结构的类名、属性名等。谢谢!
  • 我假设你有一个 wsdl 用于响应来自的端点?这会让生活更轻松。
  • 我刚刚尝试了 xsd.exe。我使用传递给它的 xml 为它生成 xsd 文件并且它正确生成了它,然后我试图从该 xsd 文件生成类。我认为它现在可以正确解析它,但现在出现不同的错误,“缺少元素'webex.com/schemas/2002/06/service/user:ticket'。”
  • 从 xml 实例推断 XSD 并不总能提供您正在寻找的确切 XSD。您希望将其定义为端点合同的一部分(作为 WSDL 的一部分发布)。

标签: asp.net xsd xsd.exe


【解决方案1】:

有一个非常体面和简单的方法来使用 XDocument 反序列化我的 xml!!!! :) :)

这是我现在的做法

var xDoc = XDocument.Parse(xmlString);
XNamespace userNS = "http://www.webex.com/schemas/2002/06/service/user";
XNamespace servNS = "http://www.webex.com/schemas/2002/06/service";
var re = from rssItem in xDoc.Descendants(servNS + "bodyContent")
                 let elementTicket = rssItem.Element(userNS + "ticket")
                 let elementApiVersion = rssItem.Element(userNS + "apiVersion")
                 where (elementTicket != null && elementApiVersion != null)
                 select new getLoginTicketResponse()
                 {
                     ticket = elementTicket.Value,
                     apiVersion = elementApiVersion.Value
                 };

getLoginTicketResponse loginTicketResponse = re.First();

我直接从 xml 中反序列化了我的类对象,不需要 XSD

让我再给你看一下我的xml

<?xml version="1.0" encoding="iso-8859-1"?>
<serv:message xmlns:serv="http://www.webex.com/schemas/2002/06/service"
xmlns:com="http://www.webex.com/schemas/2002/06/common"
xmlns:use="http://www.webex.com/schemas/2002/06/service/user">
    <serv:header>
        <serv:response>
            <serv:result>SUCCESS</serv:result>
            <serv:gsbStatus>BACKUP</serv:gsbStatus>
        </serv:response>
    </serv:header>
    <serv:body>
        <serv:bodyContent xsi:type="use:getLoginTicketResponse"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <use:ticket>5e9733eb9efeb02d80aa0551ef7e9ccd</use:ticket>
            <use:apiVersion>WebEx XML API V3.9.0</use:apiVersion>
        </serv:bodyContent>
    </serv:body>
</serv:message>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    相关资源
    最近更新 更多