我有两个XELEMENTS XR
和XTemp
。
我的XR
包含:
<result xmlns="http://abc.com/test">
<report>
<unit unit_number="1" id="S1">
<classification>Subject</classification>
<claim_reported count="0" status="No claims reported" />
</unit>
<unit unit_number="2" id="S2">
<classification>Subject</classification>
<claim_reported count="0" status="No claims reported" />
</unit>
<unit unit_number="3" id="V1">
<classification>Vehicle</classification>
<claim_reported count="1" status="Claims reported" />
</unit>
......
</report>
</result>
我的XTemp
包含:
<result xmlns="http://abc.com/test">
<report>
<unit unit_number="1" id="S3">
<classification>Subject</classification>
<claim_reported count="1" status="Claims reported" />
</unit>
<unit unit_number="2" id="S4">
<classification>Subject</classification>
<claim_reported count="4" status="Claims reported" />
</unit>
<unit unit_number="3" id="V2">
<classification>Vehicle</classification>
<claim_reported count="0" status="No claims reported" />
</unit>
<unit unit_number="3" id="V3">
<classification>Vehicle</classification>
<claim_reported count="2" status="Claims reported" />
</unit>
......
</report>
</result>
尝试根据某个条件从<unit>
中提取所有XTemp
个元素,并将其添加到XR
。
条件是:获取id为“V”的所有<unit>
个元素。
下面的代码是我能想到的最好的代码。
但是,我得到Object reference not set to an instance
错误。
XR.Descendants(xmlns + "unit").LastOrDefault().AddAfterSelf(XTemp.Descendants(xmlns + "unit")
.Where(x => x.Element(xmlns + "unit").Attribute("id").Value.ToUpper().Contains("V")));
提前致谢
BB
答案 0 :(得分:2)
你的问题出现在这段代码中:
.Where(x => x.Element(xmlns + "unit").Attribute("id")...
在查询中,您已经查询了unit
个元素。 unit
不包含嵌套unit
,这就是您获得NullReferenceException
的原因。
将其更改为:.Where(x => x.Attribute("id")...
就个人而言,我发现您的查询难以阅读。首先,LastOrDefault
意味着你可能期望存在一个空值,但是你正在寻找其余的查询而不解决它。其次,您不需要找到最后一个unit
元素和AddAfterSelf
。相反,您可以直接Add
到report
元素,元素将附加到结尾:
var query = xtemp.Descendants(xmlns + "unit")
.Where(e => e.Attribute("id").Value.StartsWith("V", StringComparison.InvariantCultureIgnoreCase));
xr.Element(xmlns + "report").Add(query);
另外,请注意我在忽略案例时如何检查“V”。与使用ToUpper
相反,这被认为是最佳做法。
编辑:根据评论,这里是一个解决方案,对所有unit
节点进行排序,同时保留非unit
节点的现有顺序。此代码考虑节点是在现有节点之前和之后,还是根本没有其他节点。
一些假设是:
unit
个节点unit
节点保持在一起,不会散布在所有其他类型的节点之间。如果它们不正确,前两个假设是很难解决的问题。
var query = xtemp.Descendants(xmlns + "unit")
.Where(e => e.Attribute("id").Value.StartsWith("V", StringComparison.InvariantCultureIgnoreCase));
var units = xr.Element(xmlns + "report").Elements(xmlns + "unit");
var beforeUnit = units.First().ElementsBeforeSelf().FirstOrDefault();
var afterUnit = units.Last().ElementsAfterSelf().FirstOrDefault();
// order based on ID starting letter, then integer value
var orderedUnits = units.Concat(query)
.OrderBy(e => e.Attribute("id").Value[0])
.ThenBy(e => int.Parse(e.Attribute("id").Value.Substring(1)))
.ToList();
// remove original unit nodes
units.Remove();
// add ordered units based on their original position
if (beforeUnit != null)
{
beforeUnit.AddAfterSelf(orderedUnits);
}
else if (afterUnit != null)
{
afterUnit.AddBeforeSelf(orderedUnits);
}
else
{
xr.Element(xmlns + "report").Add(orderedUnits);
}