2016-12-21 7 views
1

以下のコードでは、XmlSchemaDocumentの要素を検索しています。要素がXmlSchemaDocumentの一部である場合、反復処理はうまく動作します。XmlSchemaDocumentの要素部分の再帰的検索

public void FindSchemaElement(string elementName, string dataType, List<XmlSchemaElement> allChildren, string parentName) 
    { 
     try 
     { 
      List<XmlSchemaElement> temp = new List<XmlSchemaElement>(); 
      temp.AddRange(allChildren); 
      foreach (XmlSchemaElement e in allChildren) 
      { 
       if (e.Name != elementName && e.RefName.Name != elementName && 
        (dataType == "" || e.SchemaTypeName.Name != dataType)) continue; 
       if (e.Parent == null || e.Parent is XmlSchema) 
       { 
        ElementToBeFound = e; 
        return; 
       } 
       var parent = e.Parent; 
       while (parent != null && parent.GetType() != typeof(XmlSchemaElement)) 
        parent = parent.Parent; 

       if (parent != null && ((XmlSchemaElement) parent).Name == parentName) 
       { 
        ElementToBeFound = e; 
        return; 
       } 
       if (parent == null || parent.GetType() == typeof(XmlSchema)) ElementToBeFound = e; 
      } 
      if (ElementToBeFound != null) return; 
      _childrenList.Clear(); 
      if (temp.Count > 0) 
       GetNextChildren(temp, dataType, elementName, parentName); 
     } 
     catch(Exception exception){Debug.WriteLine("FindSchemaElement: "+exception.Message);} 
    } 

子供の取得:GetChildrenメソッドで

private void GetNextChildren(List<XmlSchemaElement> allChildren, string dataType, string elementName, string parentName = "") 
     { 
      try 
      { 
       foreach (XmlSchemaElement e in allChildren) 
        GetChildren(e); 
       if (parentName != string.Empty) 
        FindSchemaElement(elementName, dataType, _childrenList, parentName); 
       else 
        FindSubsGroups(elementName, dataType, _childrenList); 
      } 
      catch (Exception ex) 
      { Debug.WriteLine("GetNextChildren: " + ex.Message); } 
     } 

() - 私はちょうど要素(シーケンス、choice要素)の種類を確認していますし、それが要素であれば、私はそれを追加してい_childrenList

しかし、要素が見つからない場合、ループに詰まり、最終的にメモリが不足します(使用している.xsdファイルがかなり大きい)。 この問題は、.xsd内にループがある場合(図のように)に気づきました。 xsd example 要素が見つからないのに反復を停止する方法はありますか?ループ?

+0

ループ内に反復を停止するための 'break'キーワードがあります。 – Smartis

+0

私はそれを知っています..しかし、いつループを止める必要があるのか​​分かりますか?すべての要素がチェックされていることを確認してから、ループを止めることができます。 – MonicaS

+0

関数 'GetChildren'と' FindSubsGroups'は何ですか?あなたもそれらを投稿できますか? – Smartis

答えて

0

あなたは既に検索したものを追跡する必要があります。 GetNextChildrenは、その要素を既にチェックしていて、それを無視できるかどうかを調べることができます。私はちょうど無限再帰を防ぐビットをやったように、あなたの主な機能から、それへの呼び出しはすべての場所で新しいHashSetのに

GetNextChildren(new HashSet<XmlSchemaElement>(), ....); 

あなたのコードビットを渡す必要があります。

private void GetNextChildren(HashSet<XmlSchemaElement> searchedElements, List<XmlSchemaElement> allChildren, string dataType, string elementName, string parentName = "") 
    { 
     try 
     { 
      foreach (XmlSchemaElement e in allChildren) 
      { 
       if (searchedElements.Contains(e) == false) 
       { 
        searchedElements.Add(e); 

        // Search for it 
        // GetNextChildren(searchedElements, ....); 
       } 
      } 
     } 
     catch (Exception ex) 
     { Debug.WriteLine("GetNextChildren: " + ex.Message); } 
    } 

あなたは、スキーマが円形でお互いを含むことができることにも注意すべきであるが(a.xsdがb.xsdとb.xsdはa.xsdを含ん含む)もありました。私は同じことが要素グループにも当てはまると思います。

+0

チャームのように働いた。時間をとっていただきありがとうございます。あなたのアイデアを少し違ったものにしました。私は項目を格納する外部HashSetを作成しました。アイテムを1つチェックしたら、それをsearchedElementsリストに追加します。新しい子をリストに追加するときに、それをsearchedElementsリストに対してチェックします。誰かが興味があれば、私は更新を投稿することができます。 – MonicaS

関連する問題