【问题标题】:XML deserialization from XSD with variable XML elements使用可变 XML 元素从 XSD 进行 XML 反序列化
【发布时间】:2011-01-12 00:33:12
【问题描述】:

我收到了一个 XSD 文件,该文件代表大量元素和相关属性。我使用 xsd.exe 创建了一个 CS 类。

问题是创建的 xml 可以包含任何或所有元素和属性。

示例 XML:

<App action="A" id="1" validate="yes"><ProductType id="5885"/><SpecType id="221"/><Qty>1</Qty><PartType id="7212"/><Part>456789</Part></App>
<App action="A" id="2" validate="yes"><ProductType id="5883"/><Qty>1</Qty><PartType id="7211"/><Part>132465</Part></App>

然后在我的代码中:

protected static void ImportProduct(string filename)
{
var counter = 0;
var xSerializer = new XmlSerializer(typeof(ProductList));
var fs = new FileStream(String.Format("{0}{1}", FilePath, filename), FileMode.Open);
var reader = XmlReader.Create(fs);
var items = (ProductList)xSerializer.Deserialize(reader);

foreach (var record in items.App)
{
    counter++;

    Console.Write(String.Format("{0}{1}", record.ProductType.id, Environment.NewLine));
    Console.Write(String.Format("{0}{1}", record.Part.Value, Environment.NewLine));

    *if (!record.SpecType.Value.Equals(null))
        Console.Write(String.Format("{0}{1}", record.SpecType.id, Environment.NewLine));
    else
        Console.Write(String.Format("{0}{1}", "No SpecType!", Environment.NewLine));

    if (counter == 10)
        break;
}

}

所以我的问题是如何根据上面的星号 (*) 行检查空/不存在的元素。

我无法以任何方式更改 xsd 或源 XML 文件,因为它们是由主要制造商生产的。

如果您需要更多信息,请告诉我。

谢谢!布拉德

【问题讨论】:

  • 有什么问题? xsd 是否对 SpecType 说 'minOccurs="0"',即 xsd.exe 生成的对象包含可为空的 SpecType(例如 int?或字符串)?如果是这样,为什么您的 (*) 行不起作用?有什么异常/问题?如果 xsd 没有说 'minOccurs="0"',我预计反序列化会崩溃。
  • 嗨 Martin,它确实有:。不知道为什么它会在那条线上中断。似乎应该,但也许是我的语法不起作用......

标签: c# xml xsd deserialization


【解决方案1】:

抱歉,XSD.EXE 和 XML 序列化不会像那样处理 XML。

创建这种性质的 XML 是因为有人认为人类应该很容易阅读和输入。他们不考虑机器是否能够使用它们。这是一个错误,你现在必须为此付出代价。

您可以做的最好的事情是创建一个 XSLT,将元素按规范顺序放置,然后创建一个表示该顺序的 XSD 并从 XSD 创建类。

【讨论】:

  • 我同意。数据绑定适用于简单的常规模式。架构越大,数据越“半结构化”,使用数据绑定就变得越笨拙和繁琐; XSLT 和 XQuery 更适合处理这类数据。
  • 好的,很好,伙计们,谢谢。我投票这个答案只是为了改变我必须做出的方向。这是他们咨询了除开发人员之外的所有人的解决方案之一。
【解决方案2】:

拥有 XSD 后,您可以使用数据集而不是 XML 阅读器。然后创建了一些自动方法来检查空值,如下例所示。

例如。这在 CalcualtionAnalysisDS 是 XSD 的示例中。

        CalcualtionAnalysisDS ds = new CalcualtionAnalysisDS();
        ds.ReadXml("calc.xml");

        foreach (CalcualtionAnalysisDS.ReportRow row in ds.Report.Rows)
        {
            if (row.IsBestSHDSLDesignClassNull)
            {

            }
        }

【讨论】:

  • 您好,darwindave,感谢您的回答。我认为这是我需要走的路线,但是当我尝试使用 MSDataSetGenerator 时,它出现了“自定义工具错误:无法生成代码。未定义的数据类型:'token'”。所以这听起来像是我上面帖子的另一个不相关的错误,但有什么想法吗?我也尝试了 xsd.exe file.xsd /d ,结果相同。 - 布拉德
  • 我通常只是将我的 XSD 拖放到 Visual Studio 中,然后自动创建代码。您可以尝试使用 xsd.exe 从 xml 创建您的 xsd,以仔细检查您的 xsd 是否正确。 "c:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\xsd" Something.xml /l:CS /classes /uri:something.com/xml/something /l:CS
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
  • 2013-02-03
相关资源
最近更新 更多