我有一些XML代表例如4组(A,B,C,D)成员之间的排列。假设A = {A1,A2},B = {B1},C = {C1,C2}和D = {D1,D2,D3}但是当前的XML不正常,因为这些成员在每个成员中以非常规方式组合回答。 “set”属性显示set的名称,“member”显示每个set的每个成员。这个XML喜欢以下内容:
<root>
<phrase permutation=ABCD>
<ans number=1>
<word set=A member=A1/>
<word set=A member=A2/>
<word set=B member=B1/>
<word set=C member=C1/>
<word set=D member=D2/>
</ans>
<ans number=2>
<word set=A member=A1/>
<word set=B member=B1/>
<word set=C member=C1/>
<word set=C member=C2/>
<word set=C member=C3/>
<word set=D member=D1/>
<word set=D member=D3/>
</ans>
</phrase>
</root>
我想把每个排列放在一个特定的答案中。每个答案应该从A和End的一个成员开始,其中一个成员为D,并且在它们之间仅使用集合B和C中的一个成员。 例如答案A1A2B1C1D2应该与A1B1C1D2,A2B1C1D2分开,答案A1B1C1C2C3D1D3应该分别对A1B1C1D1,A1B1C1D3,A1B1C2D1,A1B1C2D3,A1B1C3D1和A1B1C3D3等最终XML喜欢如XML所示:
<root>
<phrase permutation=ABCD>
<ans number=1>
<word set=A member=A1/>
<word set=B member=B1/>
<word set=C member=C1/>
<word set=D member=D2/>
</ans>
<ans number=2>
<word set=A member=A2/>
<word set=B member=B1/>
<word set=C member=C1/>
<word set=D member=D2/>
</ans>
<ans number=3>
<word set=A member=A1/>
<word set=B member=B1/>
<word set=C member=C1/>
<word set=D member=D1/>
</ans>
<ans number=4>
<word set=A member=A1/>
<word set=B member=B1/>
<word set=C member=C1/>
<word set=D member=D3/>
</ans>
<ans number=5>
<word set=A member=A1/>
<word set=B member=B1/>
<word set=C member=C2/>
<word set=D member=D1/>
</ans>
<ans number=6>
<word set=A member=A1/>
<word set=B member=B1/>
<word set=C member=C2/>
<word set=D member=D3/>
</ans>
<ans number=7>
<word set=A member=A1/>
<word set=B member=B1/>
<word set=C member=C3/>
<word set=D member=D1/>
</ans>
<ans number=8>
<word set=A member=A1/>
<word set=B member=B1/>
<word set=C member=C3/>
<word set=D member=D3/>
</ans>
</phrase>
</root>
我希望我的问题清楚,你可以帮助我。 感谢
答案 0 :(得分:5)
好的,首先:请注意,在你的XML属性中没有引用,因此.NET的标准XML处理将无法读取开箱即用的内容 - 我只是纠正了那些以编写下面的解决方案。
var original = XDocument.Parse(/* your XML as string */);
var normalized = new XDocument(original);
foreach (var phraseNode in normalized.Root.Elements("phrase"))
{
phraseNode.Elements().Remove();
int ansNo = 1;
foreach(var answer in original.Root
.Elements("phrase")
.Single(p => p.Attribute("permutation").Value
== phraseNode.Attribute("permutation").Value)
.Elements("ans"))
{
var groupedWords = answer.Elements("word")
.GroupBy(w => w.Attribute("set").Value)
.ToArray();
var newAnswers = groupedWords.Skip(1)
.Aggregate(
groupedWords[0].Select(w => Enumerable.Repeat(w, 1)),
(combinations, newWords) =>
combinations.Join(newWords,
c => 1,
w => 1,
(c, w) => c.Concat(new[] { w })));
foreach (var newAnswer in newAnswers)
{
var ansNode = new XElement("ans", new XAttribute("number", ansNo++));
ansNode.Add(newAnswer.Select(w => new XElement(w)).ToArray());
phraseNode.Add(ansNode);
}
}
}
如果您不了解LINQ to XML,那么一开始可能会有点吓人;希望通过一些轻松的阅读或先验知识,唯一更复杂的(相对来说当然!)位可能是生成排列的实际代码(newAnswers
var初始化的部分) - 你可以采用面值或者尝试更多地了解LINQ如何加入工作。
另外 - 请注意,这并没有考虑任何重型优化;在99,99%的案例中,这应该不是一个问题。