使用C#LINQ

时间:2016-10-20 14:53:52

标签: c# xml linq ssis

我在VS2012的脚本转换中使用c#和LINQ来解析复杂的xml soap消息。我无法弄清楚如何循环遍历xml并获取我想要的所有元素。 xml在下面。这只是返回的一部分。每件商品有48个间隔,一般为5-6件。

<return>
<item>
    <interval>
        <intervalDate>
            <day>8</day>
            <month>7</month>
            <year>2016</year>
        </intervalDate>
        <intervalTime>
            <hours>0</hours>
            <militaryTime>true</militaryTime>
            <minutes>0</minutes>
            <seconds>0</seconds>
        </intervalTime>
        <laborType>forecasted</laborType>
        <volume>0.0</volume>
    </interval>
    <interval>
        <intervalDate>
            <day>8</day>
            <month>7</month>
            <year>2016</year>
        </intervalDate>
        <intervalTime>
            <hours>0</hours>
            <militaryTime>true</militaryTime>
            <minutes>30</minutes>
            <seconds>0</seconds>
        </intervalTime>
        <laborType>forecasted</laborType>
        <volume>0.0</volume>
    </interval>
    <jobCode>1</jobCode>
    <jobName>SERVER</jobName>
</item>
<item>
    <interval>
        <intervalDate>
            <day>8</day>
            <month>7</month>
            <year>2016</year>
        </intervalDate>
        <intervalTime>
            <hours>0</hours>
            <militaryTime>true</militaryTime>
            <minutes>0</minutes>
            <seconds>0</seconds>
        </intervalTime>
        <laborType>forecasted</laborType>
        <volume>0.0</volume>
    </interval>
    <interval>
        <intervalDate>
            <day>8</day>
            <month>7</month>
            <year>2016</year>
        </intervalDate>
        <intervalTime>
            <hours>0</hours>
            <militaryTime>true</militaryTime>
            <minutes>30</minutes>
            <seconds>0</seconds>
        </intervalTime>
        <laborType>forecasted</laborType>
        <volume>0.0</volume>
    </interval>
    <jobCode>50</jobCode>
    <jobName>Cashier</jobName>
</item>

我需要将数据输出到5列,datetime,laborType,laborVolume,laborJobCode和laborJobName。

laborDateTime | laborType | laborVolume | laborJobCode | laborJobName

2016-08-07 00:00:00.000 |预测| 0 | 1 |服务器

2016-08-07 00:30:00.000 |预测| 0 | 1 |服务器

2016-08-07 01:00:00.000 |预测| 0 | 1 |服务器

2016-08-07 01:30:00.000 |预测| 0 | 1 |服务器

我无法在网上找到任何显示如何执行此操作的示例。如果我遍历Interval,我返回预期的行数但无法获取JobCode和JobName。

    public override void CreateNewOutputRows()
{
    /*
      Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
      For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
    */

    String content = Variables.XMLString;

    XElement xdoc = XElement.Parse(content);

    var Interval = from interval in xdoc.Descendants("interval")
                   select new
                   {
                             laborIntervalDay = interval.Element("intervalDate").Element("day").Value,
                             laborIntervalMonth = interval.Element("intervalDate").Element("month").Value,
                             laborIntervalYear = interval.Element("intervalDate").Element("year").Value,
                             laborIntervalHour = interval.Element("intervalTime").Element("hours").Value,
                             laborIntervalMinutes = interval.Element("intervalTime").Element("minutes").Value,
                             laborIntervalSeconds = interval.Element("intervalTime").Element("seconds").Value,
                             laborIntervalMilitary = interval.Element("intervalTime").Element("militaryTime").Value,
                             laborType = interval.Element("laborType").Value,
                             laborVolume = interval.Element("volume").Value
                   };


            foreach (var q in Interval)
            {
                try
                {
                    DateTime dtBusinessDate = new DateTime(Convert.ToInt32(q.laborIntervalYear), Convert.ToInt32(q.laborIntervalMonth), Convert.ToInt32(q.laborIntervalDay), Convert.ToInt32(q.laborIntervalHour), Convert.ToInt32(q.laborIntervalMinutes), Convert.ToInt32(q.laborIntervalSeconds));
                    OUTLaborBuffer.AddRow();
                    OUTLaborBuffer.laborDateTime = dtBusinessDate;
                    OUTLaborBuffer.laborType = Convert.ToString(q.laborType);
                    OUTLaborBuffer.laborVolume = Convert.ToDouble(q.laborVolume);
                    //OUTLaborBuffer.laborJobCode = Convert.ToInt64(p.laborJobCode);
                    //OUTLaborBuffer.laborJobName = p.laborJobName;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error Message: " + ex.Message + " Message Detail: " + ex.StackTrace);
                }
            }

    }

我还尝试循环使用Labor和Interval,但这不正确,因为它将当前迭代的Job的JobCode / JobName分配给所有间隔。如果有5个项目,那么我最终会得到预期行数的5倍。

        var Interval = from interval in xdoc.Descendants("interval")
                   select new
                   {
                             laborIntervalDay = interval.Element("intervalDate").Element("day").Value,
                             laborIntervalMonth = interval.Element("intervalDate").Element("month").Value,
                             laborIntervalYear = interval.Element("intervalDate").Element("year").Value,
                             laborIntervalHour = interval.Element("intervalTime").Element("hours").Value,
                             laborIntervalMinutes = interval.Element("intervalTime").Element("minutes").Value,
                             laborIntervalSeconds = interval.Element("intervalTime").Element("seconds").Value,
                             laborIntervalMilitary = interval.Element("intervalTime").Element("militaryTime").Value,
                             laborType = interval.Element("laborType").Value,
                             laborVolume = interval.Element("volume").Value
                   };

    var Labor = from item in xdoc.Descendants("item")
                         select new
                         {
                             laborJobCode = item.Element("jobCode").Value,
                             laborJobName = item.Element("jobName").Value,
                         };

    foreach (var p in Labor)
    {
        // Save check information
        try
        {

            foreach (var q in Interval)
            {
                try
                {
                    DateTime dtBusinessDate = new DateTime(Convert.ToInt32(q.laborIntervalYear), Convert.ToInt32(q.laborIntervalMonth), Convert.ToInt32(q.laborIntervalDay), Convert.ToInt32(q.laborIntervalHour), Convert.ToInt32(q.laborIntervalMinutes), Convert.ToInt32(q.laborIntervalSeconds));
                    OUTLaborBuffer.AddRow();
                    OUTLaborBuffer.laborDateTime = dtBusinessDate;
                    OUTLaborBuffer.laborType = Convert.ToString(q.laborType);
                    OUTLaborBuffer.laborVolume = Convert.ToDouble(q.laborVolume);
                    OUTLaborBuffer.laborJobCode = Convert.ToInt64(p.laborJobCode);
                    OUTLaborBuffer.laborJobName = p.laborJobName;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error Message: " + ex.Message + " Message Detail: " + ex.StackTrace);
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error Message: " + ex.Message + " Message Detail: " + ex.StackTrace);
        }

    }


}

我在网上找到了一些复杂的xml被解析的例子,如下所示:

        var Labor = from item in xdoc.Descendants("item")
                         select new
                         {
                             laborJobCode = item.Element("jobCode").Value,
                             laborJobName = item.Element("jobName").Value,
                             laborInterval = (from interval in xdoc.Descendants("interval")
                                              select new
                                              {
                                                laborIntervalDay = interval.Element("intervalDate").Element("day").Value,
                                                laborIntervalMonth = interval.Element("intervalDate").Element("month").Value,
                                                laborIntervalYear = interval.Element("intervalDate").Element("year").Value,
                                                laborIntervalHour = interval.Element("intervalTime").Element("hours").Value,
                                                laborIntervalMinutes = interval.Element("intervalTime").Element("minutes").Value,
                                                laborIntervalSeconds = interval.Element("intervalTime").Element("seconds").Value,
                                                laborIntervalMilitary = interval.Element("intervalTime").Element("militaryTime").Value,
                                                laborType = interval.Element("laborType").Value,
                                                laborVolume = interval.Element("volume").Value
                                              })
                         };

我在这种结构中发现的例子是输出ToList,我不知道如何以这种格式输出间隔的后代。你知道如何做到这一点吗?

2 个答案:

答案 0 :(得分:0)

这样的事情可以解决问题:

    public dynamic OUTLaborBuffer;
    public dynamic Variables;

    public void CreateNewOutputRows()
    {
        String content = Variables.XMLString;
        XElement data = XElement.Parse(content);

        foreach (var item in data.XPathSelectElements("//item"))
        {
            var jobCode = item.Element("jobCode").Value;
            var jobName = item.Element("jobName").Value;

            foreach (var interval in item.XPathSelectElements("//interval"))
            {
                var laborIntervalDay = interval.Element("intervalDate").Element("day").Value;
                var laborIntervalMonth = interval.Element("intervalDate").Element("month").Value;
                var laborIntervalYear = interval.Element("intervalDate").Element("year").Value;
                var laborIntervalHour = interval.Element("intervalTime").Element("hours").Value;
                var laborIntervalMinutes = interval.Element("intervalTime").Element("minutes").Value;
                var laborIntervalSeconds = interval.Element("intervalTime").Element("seconds").Value;
                var laborIntervalMilitary = interval.Element("intervalTime").Element("militaryTime").Value;
                var laborType = interval.Element("laborType").Value;
                var laborVolume = interval.Element("volume").Value;

                DateTime dtBusinessDate = new DateTime(Convert.ToInt32(laborIntervalYear), Convert.ToInt32(laborIntervalMonth), Convert.ToInt32(q.laborIntervalDay), Convert.ToInt32(laborIntervalHour), Convert.ToInt32(laborIntervalMinutes), Convert.ToInt32(laborIntervalSeconds));
                OUTLaborBuffer.AddRow();
                OUTLaborBuffer.laborDateTime = dtBusinessDate;
                OUTLaborBuffer.laborType = Convert.ToString(laborType);
                OUTLaborBuffer.laborVolume = Convert.ToDouble(laborVolume);
                OUTLaborBuffer.laborJobCode = Convert.ToInt64(jobCode);
                OUTLaborBuffer.laborJobName = jobName;
            }
        }
    }

随时将XPathSelectElements更改回Descendants

答案 1 :(得分:0)

我能够通过使用parent来循环访问间隔时获取JobCode和JobName来解决这个问题。我的基础是这个例子:Linq on Complex XML

以下是我最终得到的代码:

public override void CreateNewOutputRows()
{
    /*
      Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
      For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
    */

    String content = Variables.XMLString;

    XElement xdoc = XElement.Parse(content);

    var Interval = from interval in xdoc.Descendants("interval")
                   select new
                   {
                       laborJobCode = interval.Parent.Element("jobCode").Value,
                       laborJobName = interval.Parent.Element("jobName").Value,
                       laborIntervalDay = interval.Element("intervalDate").Element("day").Value,
                       laborIntervalMonth = interval.Element("intervalDate").Element("month").Value,
                       laborIntervalYear = interval.Element("intervalDate").Element("year").Value,
                       laborIntervalHour = interval.Element("intervalTime").Element("hours").Value,
                       laborIntervalMinutes = interval.Element("intervalTime").Element("minutes").Value,
                       laborIntervalSeconds = interval.Element("intervalTime").Element("seconds").Value,
                       laborIntervalMilitary = interval.Element("intervalTime").Element("militaryTime").Value,
                       laborType = interval.Element("laborType").Value,
                       laborVolume = interval.Element("volume").Value
                   };

    foreach (var q in Interval) 
        {
            try
                {
                    DateTime dtBusinessDate = new DateTime(Convert.ToInt32(q.laborIntervalYear), Convert.ToInt32(q.laborIntervalMonth), Convert.ToInt32(q.laborIntervalDay), Convert.ToInt32(q.laborIntervalHour), Convert.ToInt32(q.laborIntervalMinutes), Convert.ToInt32(q.laborIntervalSeconds));
                    OUTLaborBuffer.AddRow();
                    OUTLaborBuffer.laborDateTime = dtBusinessDate;
                    OUTLaborBuffer.laborType = Convert.ToString(q.laborType);
                    OUTLaborBuffer.laborVolume = Convert.ToDouble(q.laborVolume);
                    OUTLaborBuffer.laborJobCode = Convert.ToInt64(q.laborJobCode);
                    OUTLaborBuffer.laborJobName =  Convert.ToString(q.laborJobName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error Message: " + ex.Message + " Message Detail: " + ex.StackTrace);
                }
            }
        }