【问题标题】:How Could I Model a Class With Arbitrary Hierarchy?我如何为具有任意层次结构的类建模?
【发布时间】:2014-04-02 04:49:55
【问题描述】:

考虑以下 XML:

<elements>
    <element attribute="value1">
        <or>
            <subelement attribute="value2" />
            <subelement attribute="value3" />
        </or>
    </element>
    <element attribute="value">
        <and>
            <subelement attribute="value4" />
            <subelement attribute="value5" />
            <or>
                <subelement attribute="value6" />
                <subelement attribute="value7" />
            </or>
        </and>
    </element>
</elements>

请注意,以下内容也是有效的:

<elements>
    <element attribute="value1">
        <subelement attribute="value2" />
    </element>
</elements>

这是这样的:

<elements>
    <element attribute="value1">
        <and>
            <or>
                <subelement attribute="value2" />
                <subelement attribute="value3" />
            </or>
            <or>
                <subelement attribute="value4" />
                <subelement attribute="value5" />
            </or>
        </and>
    </element>
</elements>

(上面的例子相当于(value2 or value3)AND(value4 or value5)

我尝试使用 xsd.exe 从 XML 创建一个 XSD 文件,然后创建一个 .cs 类,但这不足以满足我的需求,因为我需要可以具有任意深度的东西。

如何在 C# 中将其建模为类?我的想法可能是某种流畅的构建器模式?

谢谢,

理查德

附:任何能够想出一种方法来验证由这种类结构创建的规则的人都会得到 /hug :)

【问题讨论】:

  • 您应该查看 Expression 树 (msdn.microsoft.com/en-us/library/bb397951.aspx)。他们的类层次结构应该给你一个如何建模的例子。
  • 是的,我调查过,但我的脑袋爆炸了。我听说这在调查表达式树时很常见:)

标签: c# .net


【解决方案1】:

以下架构定义正确验证了您的所有 3 个 XML 示例。不幸的是,XSD.exe 在尝试将其转换为 C# 代码时因堆栈溢出异常而崩溃。但是,将 xsd 文件设置为架构 inside visual studio 会使 xml 编辑器正常工作,并会指出您的 xml 违反的任何验证规则。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="schema"
    targetNamespace="http://tempuri.org/schema.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/schema.xsd"
    xmlns:mstns="http://tempuri.org/schema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
  <xs:element name="elements">
    <xs:complexType>
      <xs:sequence>
        <xs:element name ="element" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:choice>
              <xs:element name="and" type="subLogic"/>
              <xs:element name="or" type="subLogic"/>
              <xs:element name="subelement" type ="subElement" />
            </xs:choice>
            <xs:attribute name="attribute"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="subLogic">
    <xs:choice minOccurs="1" maxOccurs="unbounded">
      <xs:element name="subelement" type="subElement"/>
      <xs:element name="and" type="subLogic"/>
      <xs:element name="or" type="subLogic"/>
    </xs:choice>
  </xs:complexType>

  <xs:complexType name="subElement">
    <xs:attribute name="attribute"/>
  </xs:complexType>
</xs:schema>

这是 xml 的更改版本,以使 Visual Studio 对其进行验证并启用智能感知。请确保您在 xml 文件的属性中的 schemas 选择器下选择了您的 xsd 文件。

<?xml version="1.0" encoding="utf-8" ?>
<elements 
    xmlns="http://tempuri.org/schema.xsd"
    xmlns:mstns="http://tempuri.org/schema.xsd">
  <element  attribute="value1">
    <and>
      <or>
        <subelement attribute="value2" />
        <subelement attribute="value3" />
      </or>
      <or>
        <subelement attribute="value4" />
        <subelement attribute="value5" />
      </or>
    </and>
  </element>
</elements>

在不了解您所代表的内容或类需要在这里做什么的情况下,这是一个模仿 XSD 的基本布局。您从此类生成的 XML 可能不会验证,但只需将正确的属性添加到类和属性中,以便所有内容都以正确的名称显示,布局正确。

class SubLogic
{
}

abstract class CollectionType : SubLogic
{
    public SubLogic[] Sub { get; set; }
}

class And : CollectionType
{
}

class Or : CollectionType
{
}

class SubElement : SubLogic
{
    public string Attribute { get; set; }
}

[XmlRoot("elements")]
class ElementCollection
{
    public Element[] Elements {Get;Set}
}

class Element
{
    public SubLogic Sub { Get; set;}
}

【讨论】:

    猜你喜欢
    • 2017-09-25
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多