2012-07-23 26 views
3

我想弄清楚爲XmlSchemaSimpleType類型的對象的「父」屬性正確的轉換類型。下面的代碼總是返回「」,因爲「父」變量驗證爲空。任何人都可以請幫助如何從simpleType的父級檢索minOccurs?謝謝!如何從C#中的XSD檢索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> 
+0

您是否嘗試過使用調試器? – leppie 2012-07-24 19:02:02

回答

1

就像我在以前question的評論說。 XmlSchemaSimpleTypeParent屬性不像您想象的那樣工作。看起來您希望它會返回<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中的位置。

這個blog已經有幾年了,但我認爲這點有幫助。您基本上必須使用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屬性)。

+0

非常感謝您的詳細澄清。我感謝你的幫助。現在我明白爲什麼它不能按照我的預期工作。 – Jyina 2012-07-25 17:30:54

+0

@Jyina只是爲了添加一些東西,而這也是當你問這個問題時由leppie所做的評論......被調試的是你的朋友。在XSD中讀入'XmlSchemaSet',在編譯XmlSchemaSet後的某個時候暫停代碼,然後查看每個屬性。我想,當你在調試器中探索它們時,它會幫助你理解什麼是事物。這和MSDN文檔['XmlSchemaSet'](http://msdn.microsoft.com/en-us/library/system.xml.schema.xmlschemaset.aspx) – psubsee2003 2012-07-26 14:57:29

+0

謝謝。這絕對有助於我更好地理解。 – Jyina 2012-07-26 18:59:50

相關問題