2016-12-21 51 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);} 
    } 

获取孩子:

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); } 
     } 

在的GetChildren() - 我只是检查元素(序列,选择元素)的类型,如果它是一个元素,我将它添加到_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来存储这些项目。一旦我检查了一个项目,我将它添加到searledElements列表中。当将新的孩子添加到列表中时,我会根据搜索到的元素列表进行检查。如果有人有兴趣,我可以发布更新。 – MonicaS