3

我试图找出 XmlSchemaSimpleType 类型对象的“父”属性的正确转换类型。下面的代码总是返回“”,因为“父”变量被验证为空。谁能帮助如何从 simpleType 的父级检索 minOccurs ?谢谢!

private string GetMinOccurs(XmlSchemaSimpleType xsdSimpleType)
{
    var parent = xsdSimpleType.Parent as XmlSchemaElement;

    if (parent == null) return "";

    return parent.MinOccurs.ToString();
}

我的 XSD 的一个例子是:

<xsd:complexType name="New_Type">
  <xsd:sequence>
    <xsd:element name="Amount" type="Amount_Type"  minOccurs="1" maxOccurs="1" />
    <xsd:element name="Name" type="Name_Type"  minOccurs="1" maxOccurs="1" />
  </xsd:sequence>
</xsd:complexType>

<xsd:simpleType name="Amount_Type">
  <xsd:annotation>
    <xsd:documentation>Amount</xsd:documentation>
  </xsd:annotation>
  <xsd:restriction base="xsd:string">
    <xsd:maxLength value="12" />
  </xsd:restriction>
</xsd:simpleType>
4

1 回答 1

1

就像我在您上一个问题的评论中所说的那样。an的Parent属性XmlSchemaSimpleType不像你想象的那样工作。看起来您希望它会返回<element>具有XmlSchemaSimpleType您指定的类型的 。

但是考虑一下这种情况:

<xsd:complexType name="New_Type">
  <xsd:sequence>
    <xsd:element name="Amount" type="Amount_Type"  minOccurs="1" maxOccurs="1" />
    <xsd:element name="OtherAmount" type="Amount_Type"  minOccurs="10" maxOccurs="15" />
    <xsd:element name="Name" type="Name_Type"  minOccurs="1" maxOccurs="1" />
  </xsd:sequence>
</xsd:complexType>

<xsd:simpleType name="Amount_Type">
  <xsd:annotation>
    <xsd:documentation>Amount</xsd:documentation>
  </xsd:annotation>
  <xsd:restriction base="xsd:string">
    <xsd:maxLength value="12" />
  </xsd:restriction>
</xsd:simpleType>

由于有 2 个具有相同类型的不同元素,它会返回哪个?从这个示例中可以看出,一个类型可以在整个 XSD 中多次使用,并且每次出现都可以有不同的MinOccurs值。如果你想得到MinOccurs,你需要找到<element>你想要的确切类型,即使该类型只使用一次。但要做到这一点,您需要知道它在 XSD 中的位置。

这个博客已经有几年历史了,但我认为这对这一点有所帮助。您基本上必须使用 找到复杂类型XmlSchemaSet.GlobalTypes[],然后您需要查看Particle属性。在您的情况下,那里将有一个XmlSchemaSequence对象(您可能需要强制转换)。然后您需要查看 items 属性以找到您的Amount元素。从那里(在另一个演员之后),你可以得到 MinOccurs。

如果您不确切知道要查找的内容,则XmlSchemaObject属性中的所有集合都具有GetEnumerator方法,因此您可以使用它foreach来帮助扫描所有内容。没有一个是通用的,所以你需要做很多铸造,但这基本上是你必须做的:

foreach (DictionaryEntry item in set.GlobalTypes)
{
    // set.GlobalTypes.GetEnumerator returns an object, so you need to cast to DictionaryEntry 
    // DictionaryEntry.Key and DictionaryEntry.Value are objects too so you need to cast again
    // Particle is an XmlSchemaObject, so you need to cast to an XmlSchemaSequence

    var seq = (XmlSchemaSequence)((XmlSchemaComplexType)item.Value).Particle;

    // XmlSchemaSequence.Items also returns an XmlSchemaObject so you need to cast again to XmlSchemaElement.

    foreach (XmlSchemaElement i in seq.Items)
    {
        if (i.SchemaTypeName == new XmlQualifiedName("Amount_Type"))
        {
            Console.WriteLine(i.MinOccursString);
        }
    }
}

但这只是展示如何到达您想去的地方的示例。您需要在每次强制转换之前进行一些类型检查,以防失败。例如,var seq = (XmlSchemaSequence)((XmlSchemaComplexType)item.Value).Particle;当它到达 XSD 中的第二种类型后会抛出异常,因为它不是复杂类型,而是简单类型。

如果您确切知道自己想要什么,则 LINQ 解决方案可能会更容易:

var xDoc = XDocument.Load("your XSD path");
var ns = XNamespace.Get(@"http://www.w3.org/2001/XMLSchema");

var minOccurs = from element in xDoc.Descendants()
                where (String)element.Attribute("type") == "Amount_Type"
                select (String)element.Attribute("minOccurs");

此方法至少可以让您快速扫描文档以查找与您匹配的任何类型Amount_Type并获取 minOccurs (或返回 null 的没有minOccurs属性)。

于 2012-07-24T20:33:01.170 回答