我正在尝试为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>
就像我在你上一个问题的评论中所说的那样。CCD_ 2的CCD_。看起来您希望它将返回具有您指定的XmlSchemaSimpleType
类型的<element>
。
但考虑一下这种情况:
<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>
当有两个不同的元素具有相同的类型时,它会返回哪个?从这个例子中可以看出,一个类型可以在整个XSD中多次使用,每次出现都可以有不同的MinOccurs
值。如果要获得MinOccurs
,则需要找到所需的确切<element>
,即使该类型只使用过一次。但要做到这一点,您需要知道它在XSD中的位置。
这个博客已经有几年的历史了,但我认为这有助于说明问题。基本上,您必须使用XmlSchemaSet.GlobalTypes[]
找到复杂类型,然后您需要查看Particle
属性。在您的情况下,其中将有一个Parent
0对象(您可能需要强制转换)。然后,您需要查看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
属性)。