我在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,我不知道如何以这种格式输出间隔的后代。你知道如何做到这一点吗?
答案 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);
}
}
}