在下面的代码中,我在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中有一个循环时我才会遇到这个问题 - 如图所示: 有什么方法可以在找不到元素时停止迭代,但是有这样的循环吗?
答案 0 :(得分:0)
您需要跟踪已搜索过的内容。 然后GetNextChildren可以检查它是否已经处理了该元素,它可以忽略它。从main函数调用它应传入一个新的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)。我认为元素组也是如此。