如何从C#中的XSD中检索minoccurs值?

时间:2012-07-23 19:03:58

标签: c# xsd

我试图找出XmlSchemaSimpleType类型的对象的“Parent”属性的正确转换类型。下面的代码总是返回“”,因为“父”变量被验证为null。任何人都可以帮助如何从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>

1 个答案:

答案 0 :(得分:1)

就像我之前在question的评论中所说的那样。 Parent的{​​{1}}属性不像您想象的那样有效。看起来您希望它会返回XmlSchemaSimpleType,其类型为您指定的<element>

但请考虑这种情况:

XmlSchemaSimpleType

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

blog已经有几年了,但我觉得有点帮助。您基本上必须使用<element>找到复杂类型,然后您需要查看XmlSchemaSet.GlobalTypes[]属性。在你的情况下,那里会有一个Particle对象(你可能需要转换)。然后,您需要查看items属性以查找XmlSchemaSequence元素。从那里(在另一个演员之后),你可以获得MinOccurs。

如果您不确切知道自己在寻找什么,Amount属性中的所有馆藏都有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); } } } 在它到达XSD中的第二个类型后将抛出异常,因为它不是复杂类型,它是一个简单类型。

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

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

此方法至少允许您快速扫描文档以查找与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"); 匹配的任何类型,并获取minOccurs(或返回null没有Amount_Type属性)。