C# 递归搜索XmlSchemaDocument的元素部分
在下面的代码中,我正在XmlSchemaDocument中搜索一个元素。如果元素是XmlSchemaDocument的一部分,那么迭代就可以正常工作C# 递归搜索XmlSchemaDocument的元素部分,c#,loops,xsd,out-of-memory,xmldocument,C#,Loops,Xsd,Out Of Memory,Xmldocument,在下面的代码中,我正在XmlSchemaDocument中搜索一个元素。如果元素是XmlSchemaDocument的一部分,那么迭代就可以正常工作 public void FindSchemaElement(string elementName, string dataType, List<XmlSchemaElement> allChildren, string parentName) { try { List&l
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);}
}
public void FindSchemaElement(string elementName、string数据类型、List allChildren、string parentName)
{
尝试
{
列表温度=新列表();
温度范围(所有儿童);
foreach(所有儿童中的XmlSchemaElement e)
{
如果(e.Name!=elementName&&e.RefName.Name!=elementName&&
(数据类型==“”| | e.SchemaTypeName.Name!=数据类型)继续;
if(e.Parent==null | | e.Parent为XmlSchema)
{
元素tobefound=e;
返回;
}
var parent=e.parent;
while(parent!=null&&parent.GetType()!=typeof(XmlSchemaElement))
父=父。父;
if(parent!=null&((XmlSchemaElement)parent).Name==parentName)
{
元素tobefound=e;
返回;
}
if(parent==null | | parent.GetType()==typeof(XmlSchema))ElementToBeFound=e;
}
if(ElementToBeFound!=null)返回;
_childrenList.Clear();
如果(温度计数>0)
GetNextChildren(临时、数据类型、元素名称、父名称);
}
catch(异常异常){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); }
}
private void GetNextChildren(列出所有子项、字符串数据类型、字符串elementName、字符串parentName=”“)
{
尝试
{
foreach(所有儿童中的XmlSchemaElement e)
儿童(e);
if(parentName!=string.Empty)
FindSchemaElement(elementName,数据类型,_childrenList,parentName);
其他的
FindSubgroups(元素名、数据类型、_childrenList);
}
捕获(例外情况除外)
{Debug.WriteLine(“GetNextChildren:+ex.Message);}
}
在GetChildren()中,我只是检查元素的类型(sequence,choice元素),如果它是一个元素,我将它添加到_childrenList中
但是,如果找不到元素,我就会陷入循环,最终耗尽内存(我使用的.xsd文件相当大)。
我注意到只有在.xsd中存在循环时才会出现此问题,如图所示:
当没有找到元素但存在这样的循环时,是否有任何方法停止迭代?您需要跟踪您已经搜索的内容。 然后GetNextChildren可以检查它是否已经处理了该元素,它可以忽略它。主函数对它的调用应该传入一个新的哈希集
GetNextChildren(new HashSet<XmlSchemaElement>(), ....);
GetNextChildren(新的HashSet(),…);
你的代码到处都是,所以我刚刚做了防止无限递归的部分
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); }
}
private void GetNextChildren(HashSet searchedElements,列出所有子项,string数据类型,string elementName,string parentName=”“)
{
尝试
{
foreach(所有儿童中的XmlSchemaElement e)
{
if(searchedElements.Contains(e)==false)
{
搜索元素。添加(e);
//搜索它
//GetNextChildren(搜索元素,…);
}
}
}
捕获(例外情况除外)
{Debug.WriteLine(“GetNextChildren:+ex.Message);}
}
您还应该注意,模式也可以在循环was中相互包含(a.xsd包括b.xsd,b.xsd包括a.xsd)。我认为元素组也是如此。您需要跟踪已搜索的内容。 然后GetNextChildren可以检查它是否已经处理了该元素,它可以忽略它。主函数对它的调用应该传入一个新的哈希集
GetNextChildren(new HashSet<XmlSchemaElement>(), ....);
GetNextChildren(新的HashSet(),…);
你的代码到处都是,所以我刚刚做了防止无限递归的部分
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); }
}
private void GetNextChildren(HashSet searchedElements,列出所有子项,string数据类型,string elementName,string parentName=”“)
{
尝试
{
foreach(所有儿童中的XmlSchemaElement e)
{
if(searchedElements.Contains(e)==false)
{
搜索元素。添加(e);
//搜索它
//GetNextChildren(搜索元素,…);
}
}
}
捕获(例外情况除外)
{Debug.WriteLine(“GetNextChildren:+ex.Message);}
}
您还应该注意,模式也可以在循环was中相互包含(a.xsd包括b.xsd,b.xsd包括a.xsd)。我认为元素组也是如此。循环中有停止迭代的
break
关键字。我知道。。但是我怎么知道循环何时需要停止呢?我需要确保所有元素都已检查,然后才能停止循环。函数GetChildren
和FindSubsGroups
的作用是什么?你也可以发布它们吗?在GetChildren()中-我只是检查元素的类型(序列,选择元素),如果它是元素,我将它添加到_childrenList中。对于子组,我只是获取相同子组的元素部分。循环中有用于停止迭代的break
关键字。我知道。。但是我怎么知道循环何时需要停止呢?我需要确保所有元素都已检查,然后才能停止循环。函数GetChildren
和FindSubsGroups
的作用是什么?你能