3

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>
4

1 に答える 1

1

私があなたの前の質問のコメントで言ったように。の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値を持つことができます。を取得したい場合は、タイプが1回だけ使用されている場合でも、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の2番目の型に到達した後、例外をスローします。これは、複合型ではなく、単純型であるためです。

必要なものが正確にわかっている場合は、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を取得できます(またはminOccurs属性がない場合はnullを返します)。

于 2012-07-24T20:33:01.170 に答える