使用 Linq to XML 创建深度对象图,重构?
我正在使用 LINQ to XML 编写一个简单的 XML 文件解析器。
我希望 XML 中的每个元素都有一个 TreeNode 对象(即简单的树结构)。我希望每个元素都是强类型的。
与我之前使用的简单循环方法(使用 System.XML)相比,它看起来丑陋且多余。有没有办法消除这里的冗余?
XElement ops = XElement.Load(@"c:\temp\exp.xml");
Tree<Element> domain = new Tree<Element>();
domain.Root = new TreeNode<Element>();
var cells =
from cell in ops.Elements("cell")
select new
{
TreeNodeObj = new TreeNode<Element>
(new Cell((string)cell.Attribute("name"), (string)cell.Attribute("name"), null)),
XElem = cell
};
foreach (var cell in cells)
{
domain.Root.AddChild(cell.TreeNodeObj);
var agents =
from agent in cell.XElem.Elements("agent")
select new
{
TreeNodeObj = new TreeNode<Element>
(new Agent((string)agent.Attribute("name"), (string)agent.Attribute("name"), null)),
XElem = agent
};
foreach (var agent in agents)
{
cell.TreeNodeObj.AddChild(agent.TreeNodeObj);
var nas =
from na in agent.XElem.Elements("node-agent")
select new
{
TreeNodeObj = new TreeNode<Element>
(new NodeAgent((string)na.Attribute("name"), (string)na.Attribute("name"), null)),
XElem = agent
};
foreach (var na in nas)
{
agent.TreeNodeObj.AddChild(na.TreeNodeObj);
}
}
}
I am writing a simple XML file parser using LINQ to XML.
I want to have a TreeNode object (i.e a simple Tree structure) for each element in the XML. I want each element to be strongly typed.
It looks ugly and redundant compared to the simple looping approach I was using before (using System.XML). Is there a way to strip out the redundancies here?
XElement ops = XElement.Load(@"c:\temp\exp.xml");
Tree<Element> domain = new Tree<Element>();
domain.Root = new TreeNode<Element>();
var cells =
from cell in ops.Elements("cell")
select new
{
TreeNodeObj = new TreeNode<Element>
(new Cell((string)cell.Attribute("name"), (string)cell.Attribute("name"), null)),
XElem = cell
};
foreach (var cell in cells)
{
domain.Root.AddChild(cell.TreeNodeObj);
var agents =
from agent in cell.XElem.Elements("agent")
select new
{
TreeNodeObj = new TreeNode<Element>
(new Agent((string)agent.Attribute("name"), (string)agent.Attribute("name"), null)),
XElem = agent
};
foreach (var agent in agents)
{
cell.TreeNodeObj.AddChild(agent.TreeNodeObj);
var nas =
from na in agent.XElem.Elements("node-agent")
select new
{
TreeNodeObj = new TreeNode<Element>
(new NodeAgent((string)na.Attribute("name"), (string)na.Attribute("name"), null)),
XElem = agent
};
foreach (var na in nas)
{
agent.TreeNodeObj.AddChild(na.TreeNodeObj);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果没有示例数据和实际类型,很难完全回答这个问题,但我会像下面这样重构它。
从最初的示例来看,我假设我们不想弄乱实体的构造函数(
Agent
等),并且我们希望保留单独的“TreeNode”
”模型,将我们的实体放入树中(而不是更改实体以将事物建模为关联的集合)。我还假设我们可以比实体更自由地使用TreeNode
,因此我引入了一个接受IEnumerable<...>< /code>,因为这允许与 LINQ 子查询一起使用:
使用下面的框架代码:
It is hard to answer this fully without sample data and actual types, but I would refactor it like below.
From the original example, I'm assuming we don't want to mess with the constructors of the entities (
Agent
etc), and that we want to retain the separate "TreeNode<T>
" model, putting our entities inside the tree (rather than changing the entities to model things as associated collections). I've also assumed that we can take more liberties withTreeNode<T>
than we can with the entities, so I've introduced a constructor that acceptsIEnumerable<...>
, since this allows use with LINQ sub-queries:With framework code below:
如果没有类和源 xml,就很难为您提供所需的确切代码,但我喜欢这样构建 XML 解析:
给定 xml:
和类:
Without your classes and source xml, it's quite hard to provide you with the exact code you're after, but here's how I like to structure my XML parsing:
Given the xml:
and the classes: