XML中的所有子节点都链接到父节点

时间:2016-08-25 08:06:40

标签: c# xml xpath

我正在尝试修复一段没有做我想做的代码。代码由一位工程师留下,他声称工作正常。他一直在使用XPATH而不是Linq,所以从短期来看我正在寻找基于XPATH的解决方案。

我搜索了网络,但无法将我发现的内容转换为有效的解决方案。

XML看起来像:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Orders>
    <Order>
        <OrderId>6175</OrderId>
        <OrderNumber>6175</OrderNumber>
        <OrderDate>2016-08-19 13:17:41</OrderDate>
        <OrderLineItems>
            <ItemName>Name of Item</ItemName>
            <Quantity>1</Quantity>
            <Meta/>
        </OrderLineItems>
    </Order>
</Orders>

他使用Visual Studio 2008创建的关于读取XML的脚本如下所示:

   public override void CreateNewOutputRows()
    {
        string filename = Variables.strFileInLoop;

        XmlDocument doc = new XmlDocument();
        doc.Load(filename);


        // loop orders
        foreach (XmlNode shipmentNode in doc.DocumentElement.SelectNodes("/Orders/Order"))
        {
            OutputOrdersBuffer.AddRow();
            String OrderId = GetNodeText("OrderId", shipmentNode).Trim();
            OutputOrdersBuffer.OrderId = OrderId;
            OutputOrdersBuffer.OrderNumber = GetNodeText("OrderNumber", shipmentNode).Trim();
            OutputOrdersBuffer.OrderDate = GetNodeText("OrderDate", shipmentNode).Trim();
            String replace = @"C:\Projects\Customername\IN\";
            OutputOrdersBuffer.FileName = filename.Replace(replace, "");

                foreach (XmlNode OrderLineItemNode in shipmentNode.SelectNodes("/Orders/Order/OrderLineItems"))
                {
                    OutputOrderLinesBuffer.AddRow();
                    OutputOrderLinesBuffer.OrderId = OrderId;
                    OutputOrderLinesBuffer.ItemName = GetNodeText("ItemName", OrderLineItemNode).Trim();
                    OutputOrderLinesBuffer.Quantity = GetNodeText("Quantity", OrderLineItemNode).Trim();
                    OutputOrderLinesBuffer.Meta = GetNodeText("Meta", OrderLineItemNode).Trim();

                }

        } 
    }

当我们尝试导入具有多个订单的XML时,会发生的情况是代码将所有OrderLineItem附加到所有订单。

因此,如果文件中有10个唯一订单,其中包含2个OrderLineItems,则它会发出10个订单,每个订单包含20个OrderLineItem。

正如我所说,我到处寻找(我认为),但我无法将我发现的内容转换为OrderLineItem仅链接到它们所属的顺序的解决方案。

1 个答案:

答案 0 :(得分:0)

订单中的迭代使用 XPath 表达式

/Orders/Order/OrderLineItems

每次都会遍历整个文档,因为起始/ in表示。这就是所有订单中都包含所有订单行的原因。

更改 XPath 表达式以将shipmentNode作为上下文项,如果 XPath 表达式不以/开头,则会隐式发生,并从那里导航到其OrderLineItems孩子应该有所帮助:

foreach (XmlNode OrderLineItemNode in shipmentNode.SelectNodes("OrderLineItems"))

XPath 开始时,命令行上的文件系统类似通常会有所帮助:上下文项的行为类似于工作目录,并且可以使用绝对路径更改目录(从/),或者是当前目录的相对路径(以./开头,也适用于 XPath )。当然 XPath 是不同的,因为它是面向集合的,但这种类比有助于进入正确的导航思维模式。