【发布时间】:2016-10-20 14:53:51
【问题描述】:
我在 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 和 labourJobName。
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,但这不正确,因为它将当前 Labor 迭代的 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,我不知道如何以这种格式输出间隔的后代。你知道如何做到这一点吗?
【问题讨论】:
-
在最后一次尝试中,尝试用
item.Descendants("interval")替换xdoc.Descendants("interval")并添加.ToArray()以确保。