目前我处理的是这样的XML类型:XML FILE http://%20drive.google.com/open?id=0By5BxgNi9eGcRldxcEZNU0FDTzQ
参考XML文件,我想检查一个节点,如果找不到该节点,我必须将该节点附加到文件中。我尝试过以下代码:
private void button12_Click(object sender, EventArgs e)
{
// XmlNodeList func_name_value = doc.GetElementsByTagName("FUNCTION-NAME-VALUE");
XmlNodeList list_def_ref = doc.GetElementsByTagName("DEFINITION-REF");
foreach (XmlNode nodeDef in list_def_ref)
{
if (nodeDef.InnerText == "/AUTOSAR/Com/ComConfig/ComSignal")
{
if (nodeDef.ParentNode.HasChildNodes)
{
XmlNodeList list = nodeDef.ParentNode.ChildNodes;
foreach (XmlNode node in list)
{
if (node.Name == "PARAMETER-VALUES")
{
XmlNodeList param_list = node.ChildNodes;
foreach (XmlNode paramNode in param_list)
{
if (paramNode.Name == "FUNCTION-NAME-VALUE")
{
XmlNodeList func_child_list = paramNode.ChildNodes;
foreach (XmlNode funChild in func_child_list)
{
if (funChild.Name == "DEFINITION-REF")
{
string tout = "/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification";
string comnotify = "/AUTOSAR/Com/ComConfig/ComSignal/ComNotification";
string invalid = "/AUTOSAR/Com/ComConfig/ComSignal/ComInvalidNotification";
if (funChild.InnerText != tout)
{
if (funChild.InnerText != comnotify)
{
//ADD ComInvalidNotification tags
XmlNode newNode = doc.CreateElement("FUNCTION-NAME-VALUE");
paramNode.AppendChild(newNode);
XmlNode defRefNode = doc.CreateElement("DEFINITION-REF");
XmlAttribute attr = doc.CreateAttribute("DEST");
attr.Value = "FUNCTION-NAME-DEF";
defRefNode.Attributes.SetNamedItem(attr);
newNode.AppendChild(defRefNode);
XmlNode val = doc.CreateElement("VALUE");
val.InnerText = "ComInvalidNotification";//ComInvalidNotification + shortName ;
newNode.AppendChild(val);
}
else
{
//ADD ComNotification tags
XmlNode newNode = doc.CreateElement("FUNCTION-NAME-VALUE");
paramNode.AppendChild(newNode);
XmlNode defRefNode = doc.CreateElement("DEFINITION-REF");
XmlAttribute attr = doc.CreateAttribute("DEST");
attr.Value = "FUNCTION-NAME-DEF";
defRefNode.Attributes.SetNamedItem(attr);
newNode.AppendChild(defRefNode);
XmlNode val = doc.CreateElement("VALUE");
val.InnerText = "ComNotification Node";//ComNotification + shortName;
newNode.AppendChild(val);
}
}
else
{
//ADD ComTimeOutNotification tags
XmlNode newNode = doc.CreateElement("FUNCTION-NAME-VALUE");
paramNode.AppendChild(newNode);
XmlNode defRefNode = doc.CreateElement("DEFINITION-REF");
XmlAttribute attr = doc.CreateAttribute("DEST");
attr.Value = "FUNCTION-NAME-DEF";
defRefNode.Attributes.SetNamedItem(attr);
newNode.AppendChild(defRefNode);
XmlNode val = doc.CreateElement("VALUE");
val.InnerText = "ComTimeoutNotification node";//ComInvalidNotification + shortName;
newNode.AppendChild(val);
}
}
}
}
}
}
}
}
}
}
doc.Save(openFileDialog1.FileName);
我收到的错误是:元素列表已更改。枚举操作无法继续。
第一次执行 foreach 循环后,我收到此错误,我应该如何克服此错误?
你这里有两个问题:
-
您正在修改您的XmlNodeList
迭代集合时。 Microsoft 的标准做法是在迭代过程中修改集合时抛出异常,例如,请参阅文档IEnumerator.MoveNext https://msdn.microsoft.com/en-us/library/system.collections.ienumerator.movenext.aspx:
例外情况
InvalidOperationException
:创建枚举器后,集合被修改。
为了避免这种异常,您可以使用for
循环并索引XmlNodeList
手动,或快照到静态List<T>并迭代它 https://stackoverflow.com/questions/604831/collection-was-modified-enumeration-operation-may-not-execute.
-
您正在搜索名为的 XML 节点<DEFINITION-REF>
and <FUNCTION-NAME-VALUE>
,但你也是creating具有该名称的节点。这意味着您在迭代早期创建的节点可能会在迭代后期找到,从而导致递归创建更多节点。我想你不想要这个。如果我的计算是正确的,您应该对满足搜索条件的所有节点进行快照,然后迭代快照,如下所示:
private static void AddMissingNodes(XmlDocument doc)
{
var query = from nodeDef in doc.GetElementsByTagName("DEFINITION-REF").Cast<XmlNode>()
where nodeDef.InnerText == "/AUTOSAR/Com/ComConfig/ComSignal"
from nodeDefSibling in nodeDef.ParentNode.ChildNodes.Cast<XmlNode>()
where nodeDefSibling.Name == "PARAMETER-VALUES"
from paramNode in nodeDefSibling.ChildNodes.Cast<XmlNode>()
where paramNode.Name == "FUNCTION-NAME-VALUE"
select new
{
paramNode = paramNode,
func_child_list = (from funChild in paramNode.ChildNodes.Cast<XmlNode>()
where funChild.Name == "DEFINITION-REF"
select funChild).ToList() // Snapshot func_child_list by calling ToList()
};
foreach (var paramNodeAndFuncChildren in query.ToList()) // Snapshot everything by calling ToList()
foreach (var funChild in paramNodeAndFuncChildren.func_child_list)
AddMissingNodes(doc, paramNodeAndFuncChildren.paramNode, funChild);
}
private static void AddMissingNodes(XmlDocument doc, XmlNode paramNode, XmlNode funChild)
{
string tout = "/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification";
string comnotify = "/AUTOSAR/Com/ComConfig/ComSignal/ComNotification";
string invalid = "/AUTOSAR/Com/ComConfig/ComSignal/ComInvalidNotification";
if (funChild.InnerText != tout)
{
if (funChild.InnerText != comnotify)
{
//ADD ComInvalidNotification tags
XmlNode newNode = doc.CreateElement("FUNCTION-NAME-VALUE");
paramNode.AppendChild(newNode);
XmlNode defRefNode = doc.CreateElement("DEFINITION-REF");
XmlAttribute attr = doc.CreateAttribute("DEST");
attr.Value = "FUNCTION-NAME-DEF";
defRefNode.Attributes.SetNamedItem(attr);
newNode.AppendChild(defRefNode);
XmlNode val = doc.CreateElement("VALUE");
val.InnerText = "ComInvalidNotification";//ComInvalidNotification + shortName ;
newNode.AppendChild(val);
}
else
{
//ADD ComNotification tags
XmlNode newNode = doc.CreateElement("FUNCTION-NAME-VALUE");
paramNode.AppendChild(newNode);
XmlNode defRefNode = doc.CreateElement("DEFINITION-REF");
XmlAttribute attr = doc.CreateAttribute("DEST");
attr.Value = "FUNCTION-NAME-DEF";
defRefNode.Attributes.SetNamedItem(attr);
newNode.AppendChild(defRefNode);
XmlNode val = doc.CreateElement("VALUE");
val.InnerText = "ComNotification Node";//ComNotification + shortName;
newNode.AppendChild(val);
}
}
else
{
//ADD ComTimeOutNotification tags
XmlNode newNode = doc.CreateElement("FUNCTION-NAME-VALUE");
paramNode.AppendChild(newNode);
XmlNode defRefNode = doc.CreateElement("DEFINITION-REF");
XmlAttribute attr = doc.CreateAttribute("DEST");
attr.Value = "FUNCTION-NAME-DEF";
defRefNode.Attributes.SetNamedItem(attr);
newNode.AppendChild(defRefNode);
XmlNode val = doc.CreateElement("VALUE");
val.InnerText = "ComTimeoutNotification node";//ComInvalidNotification + shortName;
newNode.AppendChild(val);
}
}
那么,如果我计算 XML 节点的数量 https://stackoverflow.com/questions/2645319/count-total-number-of-xmlnodes-in-c-sharp之前和之后:
var fileName = @"D:\Temp\Question36740480\autosar_ecucvalues_Fx4_L.xml";
var newFileName = @"D:\Temp\Question36740480\autosar_ecucvalues_Fx4_L_NEW.xml";
var doc = new XmlDocument();
doc.Load(fileName);
int countBefore = doc.SelectNodes("descendant::*").Count;
AddMissingNodes(doc);
int countAfter = doc.SelectNodes("descendant::*").Count;
Debug.WriteLine(string.Format("Added {0} nodes", countAfter - countBefore));
doc.Save(newFileName);
Debug.WriteLine("Wrote: " + newFileName);
我看到 342 个节点被添加到XmlDocument
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)