我有以下格式的示例xml文件: -
另外,我有一个如下所示的Control类:
class Control
{
private string id;
public string Id
{
get { return id; }
set { id = value; }
}
private string controlType;
public string ControlType
{
get { return controlType; }
set { controlType = value; }
}
private string searchProperties;
public string SearchProperties
{
get { return searchProperties; }
set { searchProperties = value; }
}
public List<Control> ChildrenControl = new List<Control>();
}
我需要阅读上面提到的XML文件并填充代码。我不知道如何递归地做到这一点。我正在考虑将Linq用于XML,但不确定如何在这种情况下递归使用它,其中父元素和子元素的类型相同。有人可以帮我解决这个问题吗?
谢谢, Harit
答案 0 :(得分:0)
<强>更新强>
尝试以下方法。它使用Linq to XML和递归函数来解析XML文档中的控件。它假定您的XML数据存在于名为“Controls.xml”的文件中,显然是您的Control类。它不是最好的代码,但它应该让你开始。
private void ParseControlsData()
{
var doc = XDocument.Load("Controls.xml");
var controls = from control in doc.Element("controls").Elements("control")
select CreateFromXElement(control);
var controlsList = controls.ToList();
Console.ReadLine();
}
private Control CreateFromXElement(XElement element)
{
var control = new Control()
{
Id = (string)element.Attribute("id"),
ControlType = (string)element.Attribute("controlType"),
SearchProperties = (string)element.Attribute("searchProperties")
};
var childrenElements = element.Element("childControls");
if (childrenElements != null)
{
var children = from child in childrenElements.Elements("control")
select CreateFromXElement(child);
control.ChildrenControl = children.ToList();
}
return control;
}
注意:
<强>更新强>
不要这样做,它对你的例子不起作用,因为你有值存储在属性中,默认情况下,DataContractSerializer + DataContractAttributes组合不支持它(没有一大堆额外的工作)。其他选项是Linq to XML(如您所建议的)和使用XmlSerializer(类似于DataContractSerializer,但使用自己的一组属性)。我会进一步研究它。
上一个答案:
将XML文档转换为对象图的一种方法是使用DataContract属性标记要创建的类,并使用DataContractSerializer。您需要做的就是确保DataContract(Name =“X”)和DataMember(Name =“Y”)匹配XML中元素的名称。
查看我在XML Element Selection上的答案,该答案正在执行您想要的操作(使用现有XML并将其转换为对象图)。您可能不必担心该用户遇到的CDATA内容,因此您的解决方案可能会更简单一些。
另外,请查看我在How to catch/send XML doc with various sub arrays?上的答案,该答案正在执行相反的操作(用户希望从对象图创建XML)。
如果你不知道,我是DataContractSerializer的粉丝:)
答案 1 :(得分:0)
您可以使用Func<>
委托来使用递归,但必须在指定实际委托逻辑之前声明它:
var xDoc = XDocument.Load("Input.xml");
Func<XElement, List<Control>> childControlsQuery = null;
childControlsQuery =
x => (from c in x.Elements("control")
select new Control
{
Id = (string)c.Attribute("id"),
ControlType = (string)c.Attribute("controltype"),
SearchProperties = (string)c.Attribute("searchproperties"),
ChildrenControl = childControlsQuery(c.Element("childControls") ?? new XElement("childControls"))
}).ToList();
var controls = childControlsQuery(xDoc.Root);
如果您确定始终有?? new XElement("childControls")
元素,即使给定控件没有任何子元素,也可以删除childControls
。
如果你确定总有一个主控制,你可以得到它:
var mainControl = controls.First();