我的情况需要其他一些眼睛。我有两个不同的XML文件,我通过LINQ语句来提供特定顺序的特定值,并且大多数情况下我都能正常工作。我缺少的只是其中一个部分的顺序,所以我希望有人可以在这里提供帮助。
我称之为模板的第一个文件:
<CARENetIn>
<transaction>
<TimeStamp value="Fri Jan 03 07:57:39 CDT 2014" />
<RequestCode value="ResetPassword" />
<RetryCount value="0" />
<ApplicationName value="CARE GENMED CLIENT" />
<PlaylistName value="ResetPassword" />
</transaction>
<payload>
<payloadItem name="LogonUserId">
<value>CARE</value>
</payloadItem>
<payloadItem name="LogonPassword">
<value>admin</value>
</payloadItem>
<payloadItem name="UserId">
<value>HJones</value>
</payloadItem>
<payloadItem name="Password">
<value>pass@word!</value>
</payloadItem>
<repeatedDataList>
<repeatedItem>
<payloadItem name="Test Key 1">
<value>Test 1</value>
</payloadItem>
<payloadItem name="Test Key 2">
<value>Test 2</value>
</payloadItem>
</repeatedItem>
<repeatedItem>
<payloadItem name="Test Key 1">
<value>Test 3</value>
</payloadItem>
<payloadItem name="Test Key 2">
<value>Test 4</value>
</payloadItem>
</repeatedItem>
</repeatedDataList>
</payload>
</CARENetIn>
我称之为播放列表的第二个文件(删除某些部分的机密性,长度和清晰度):
<CARENet>
<CARENetID>
<sequence>0</sequence>
</CARENetID>
<action type="SetText">
<sequence>1</sequence>
<fieldName>LogonUserId</fieldName>
</action>
<action type="SetText">
<sequence>2</sequence>
<fieldName>LogonPassword</fieldName>
</action>
<action type="PressButton">
<sequence>3</sequence>
<fieldName>Logon</fieldName>
</action>
<action type="TabSelect">
<sequence>4</sequence>
<fieldName>Modify</fieldName>
</action>
<action type="SetListBoxItem">
<sequence>5</sequence>
<fieldName>UserId</fieldName>
</action>
<action type="PressButton">
<sequence>6</sequence>
<fieldName>LoadUser</fieldName>
</action>
<action type="SetText">
<sequence>7</sequence>
<fieldName>Password</fieldName>
</action>
<action type="PressButton">
<sequence>8</sequence>
<fieldName>Update</fieldName>
</action>
<action type="SetText">
<sequence>9</sequence>
<fieldName>Test Key 1</fieldName>
</action>
<action type="SetListBoxItem">
<sequence>10</sequence>
<fieldName>GroupID</fieldName>
</action>
<action type="SetText">
<sequence>11</sequence>
<fieldName>Test Key 2</fieldName>
</action>
<action type="PressButton">
<sequence>12</sequence>
<fieldName>Exit</fieldName>
</action>
</CARENet>
现在,我有一个LINQ语句加入这两个列表,它们本质上应该获取所有值,并重复使用两者之间的action标记重复数据列表标记。以下是声明:
XDocument template = XDocument.Load(@"C:\CARE\Playlists\XML Repeated Test.xml");
XDocument playlist = XDocument.Load(@"C:\CARE\Playlists\RepeatedPlaylist.xml");
var action = from actionList in playlist.Descendants(XMLPlaylistAction.Root)
join payloadList in template.Descendants(XMLIn.PayloadItem)
on actionList.Descendants(XMLPlaylistAction.FieldName).First().Value.ToLower() equals
payloadList.Attributes().First().Value.ToLower()
into joined
from subList in joined.DefaultIfEmpty()
select new
{
ID = (subList == null ? string.Empty : subList.Attributes().First().Value.ToString()),
Value = (subList == null ? string.Empty : subList.Elements().First().Value.ToString()),
Action = actionList.Attributes().First().Value.ToString()
};
现在,当我循环播放它们的结果时,我得到了我需要的所有部分,并且大部分都按照正确的顺序。声明使用了FirstOrDefault而不是First,并且至少按顺序获得了重复值,但是这两个值之间有一个步骤,它显示在重复值之后。它需要每次都在重复的数据值中发生。
如何调整LINQ语句以显示重复值之间的步骤?
所以,只是为了澄清,结果看到了:
LogonUserID - SetText
LogonPassword - SetText
PressButton
TabSelect
UserId - SetListBoxItem
PressButton
Password - SetText
PressButton
TestKey1 - SetText
TestKey2 - SetText
TestKey1 - SetText
TestKey2 - SetText
SetListBoxItem
PressButton
我想看到的是:
LogonUserID - SetText
LogonPassword - SetText
PressButton
TabSelect
UserId - SetListBoxItem
PressButton
Password - SetText
PressButton
TestKey1 - SetText
SetListBoxItem
TestKey2 - SetText
TestKey1 - SetText
SetListBoxItem
TestKey2 - SetText
PressButton
我会很感激这里的任何想法。谢谢你们!
答案 0 :(得分:1)
我的想法怎么样,虽然这不是最好的方法。
我使用struct MyResult
而不是匿名类型。
public struct MyResult
{
public string ID { get; set; }
public string Value { get; set; }
public string Action { get; set; }
public int Sequence { get; set; }
public override string ToString()
{
return (ID != null) ? string.Format("{0} - {1}", ID, Action) : Action;
}
}
以下是获得所需结果的代码。
XDocument template = XDocument.Load(@"C:\CARE\Playlists\XML Repeated Test.xml");
XDocument playlist = XDocument.Load(@"C:\CARE\Playlists\RepeatedPlaylist.xml");
var listSrc = (from payloadList in template.Descendants("payloadItem")
join actionList in playlist.Descendants("action")
on payloadList.Attributes().First().Value.ToLower() equals
actionList.Descendants("fieldName").First().Value.ToLower()
select new MyResult
{
Sequence = int.Parse(actionList.Elements("sequence").First().Value),
ID = payloadList.Attributes().First().Value,
Value = payloadList.Elements().First().Value,
Action = actionList.Attributes().First().Value
}).ToList();
List<MyResult> listDst = new List<MyResult>();
listDst.Add(listSrc.First());
for (int i = 0; i < listSrc.Count() - 1; i++)
{
if (listSrc[i].Sequence < listSrc[i + 1].Sequence)
{
for (int j = listSrc[i].Sequence + 1; j < listSrc[i + 1].Sequence; j++)
{
listDst.Add(new MyResult
{
Action = playlist.Descendants("action")
.First(_ => _.Elements("sequence").First().Value == j.ToString())
.Attributes().First().Value
});
}
}
listDst.Add(listSrc[i + 1]);
}
for (int i = listSrc.Last().Sequence; i <= int.Parse(playlist.Descendants("action").Elements("sequence").Last().Value); i++)
{
listDst.Add(new MyResult
{
Action = playlist.Descendants("action")
.First(_ => _.Elements("sequence").First().Value == i.ToString())
.Attributes().First().Value
});
}
foreach (var item in listDst)
{
Console.WriteLine(item);
}