动态映射xml字段到静态对象

时间:2011-08-19 18:41:49

标签: c# wpf xml infopath

我想为用户提供一个可视DOM,如XML结构的表示(这里是一个完整的infopath表单),并允许他们指定要映射到静态编译对象的xml数据的哪些元素。

作为一个例子,用户有一个infopath表单,允许他们输入销售交易,他们填写并提交,应用程序应该允许他们以infopath形式查看数据的结构(友好的,树视图的方式)并指定它应如何映射到销售交易的静态表示(想想可能出现在“交易”表中的行)。

Infopath表格(xml来源)不受我控制。

我正在寻找有关如何显示XML树视图的建议,并允许与它进行交互以指定映射(可能是拖放?)。

这将是一个wpf应用程序(我知道我必须在表单主机中托管infopath控件,因为它不是wpf)用c#编写,我们更愿意使用Microsoft提供的.Net元素或者打开源软件。

编辑:作为一个更全面的例子,假设有一个infopath表单导致xml看起来像:

<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,salesman,amount,items collection等,但是注释和其他一些数据被忽略,并且表单将不相同(info path提供可配置的表单用户将数据输入到他们想要的系统中或以任何一致的方式命名。用户正在指定映射。

2 个答案:

答案 0 :(得分:1)

我将采用最简单的方式 - 从给定的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 :(得分:1)

Andreas的解决方案看起来似乎是一个很好的第一步。看起来像你的输入,它需要递归到节点的属性以及。

我对您的计划的描述将是:

  1. 构建一个显示所有数据的控件(Andreas使用TreeView)
    • 您可能希望显示每个
    • 的名称和值
  2. 为您要加载的对象构建类似的控件
  3. 设置事件以构建映射
    • 你提到在它们之间拖动
    • 或者如果它们都是复选框树,可以让它们在Xml树中检查一个,然后在对象树中检查一个并重置两个,构建一个创建的映射列表
  4. 最后使用该映射列表填充对象
  5. 我没有看到任何简单的方法,它做了很多工作,而且很多工作取决于实现的细节,所以我不能只给你提供可以做到的代码。

    我认为如何让它快速运作:

    1. 通过xml生成xpaths,然后查找每个值
    2. 将所有这些xpath以及它们所代表的名称和值加载到要显示给用户的表中
      • 使用“名称”,“值”,“xpath” - 隐藏的列,“加载到属性” - 下拉列表
    3. 构建一个下拉列表,列出对象中的每个属性,将其显示在向用户显示的表中的列中
    4. 基本上我认为你需要将其分解为更小的步骤,并在每个特定步骤中寻求帮助。