动态地将xml字段映射到一个静态对象
我想为用户提供一个类似于XML结构(这里是一个完整的信息表单)的可视化DOM,并允许它们指定他们想要映射到的xml数据的哪些元素一个静态编译的对象。动态地将xml字段映射到一个静态对象
作为一个例子,用户有一个infopath表单,允许他们输入销售交易,填写并提交,应用程序应允许他们查看infopath表单中的数据结构(在友好,树视图方式),并指定它应该如何映射到销售交易的静态表示(考虑可能在“交易”表中出现的行)。
Infopath窗体(xml源代码)不受我控制。
我在寻找关于如何显示XML树形视图的建议,并允许与它交互以指定映射(可能是拖放?)。
这将在一个wpf应用程序(我知道我将不得不在一个表单主机中托管infopath控件,因为它不是wpf),我们希望使用Microsoft提供的.Net元素或开源软件。
编辑:作为一个更详尽的例子,假设有导致XML的InfoPath表单,看起来像:
<Deal id="1" dateBooked="2011-01-01" term="24" language="en-us">
<Salesman>Jim Flowers</Salesman>
<FinancedAmount>55000.00</FinancedAmount>
<Items>
<Item id="1" quantity="10" unitPrice="10000.00">Tractor</Item>
<Item id="2" quantity="1" unitPrice="5000.00">Spare Blade</Item>
</Items>
<Notes>
<Note dateAdded="2010-09-20">Customer needs a spare blade</Note>
<Note dateAdded="2010-12-31">Customer wants to sign the deal on new year's day, I find this odd...</Note>
</Deal>
我希望用户,在运行时,并以直观的方式(用户将不会知道xpath ...)将本文档树视图的特定节点映射到“Deal”对象上的字段。因此,Deal对象可能有一个ID,销售员,金额,项目集合等需要填充,但注释和一些其他数据被忽略,并且表单将不会相同(信息路径提供了可配置的表单用户可以根据需要将数据导入系统)或以任何一致的方式命名。用户正在指定映射。
Andreas的解决方案看起来像是一个很好的第一步。看起来像你的输入,它需要递归到节点的属性中。
我你的计划的描述是:
- 构建一个显示所有的数据的控制(安德烈亚斯使用一个TreeView)
- 你可能会想显示的名称和每个值
- 建立一个类似的控制要装载到
- 设置事件建立映射对象
- 你提到他们
- 之间拖动或者,如果他们都复选框树也许他们检查一个XML树,然后一个对象树和复位两个,建立映射的列表中创建
- 最后使用映射表来填充对象
我看不出有什么简单的方法来做到这一点,它的很多工作,很多它取决于执行的细节,所以我不能只是给你可以做到的代码。通过XML
- 递归,你去对每一个值
- 加载所有的XPath和名称和值生成的XPath:
我怎么觉得我可能这样做是为了得到它快速工作他们代表到表中要显示给用户
- 随着列“姓名”,“价值”,“XPath的” -hidden,“加载到房产” -dropdown
- 卜ild下拉列表中的每个属性在你的对象中,在表中的一列中显示给用户
基本上我相信你需要把它分解成更小的步骤,并搜索每个特定步骤的帮助。
我会走最简单的方式 - 从给定的XML创建一个树视图,并添加一个复选框到每个节点。当用户单击“确定”(或其他)按钮时,您将检查所有选中的复选框并构建您的对象。
创建从一个XML树视图是相当简单 - 这应该工作
public static class TreeViewExtensions
{
public static void LoadXml(this TreeView treeview, XmlDocument doc)
{
treeview.Nodes.Clear();
RecursiveImport(treeview.Nodes, doc.ChildNodes);
}
private static void RecursiveImport(TreeNodeCollection tvNodes, XmlNodeList xmlNodes)
{
TreeNode tvNode;
foreach (XmlNode xmlNode in xmlNodes)
{
tvNode = new TreeNode(xmlNode.Name);
if (xmlNode.ChildNodes.Count > 0)
RecursiveImport(tvNode.Nodes, xmlNode.ChildNodes);
tvNodes.Add(tvNode);
}
}
}
编辑:嗯,基本上,你可以列出一个列表框中的所有XML字段,以及所有(我没有然而测试一下吧!)你的对象在另一个领域。当用户将拖放的1字段拖到对象的列表框中时,您需要将此关系保存在另一个对象中。
我不熟悉使用WPF但这篇文章似乎还不错 - http://www.codeproject.com/KB/dotnet/csdragndrop01.aspx
“链接”枚举类型查找试图达到什么非常有前途的。
+1一个很好的答案,但不一定是我问的问题。我需要从文档中任意命名的xml节点,我没有指定映射到我指定的对象。映射是重要的部分。我会尝试在编辑问题时更清楚地说明这一点。 – marr75
更新了答案...希望我能更好地理解这次的要求;-) – int32