2016-04-28 58 views
2

我想要得到的是每个元素的值列表或数组值。C#linq xml缺少元素给出异常

但是,如果子元素丢失,我想要一个空字符串。

这是我的代码,但是当孩子x缺少它不会返回""而是抛出IllegalOperation例外:

var firstphs = xliff.Descendants() 
        .Elements(xmlns + "trans-unit") 
        .Elements(xmlns + "seg-source") 
        .Elements(xmlns+ "mrk") 
        .Where(e => e.Attribute("mtype").Value == "seg") 
        .Select(e => e.Elements(xmlns+"x").FirstOrDefault().Attribute("id").Value ?? "") 
        .ToArray(); 

有人能指出什么是错的代码,以及如何纠正它?谢谢。

回答

2

访问属性的情况下FirstOrDefault()返回null会导致异常。你可以试试这种方式来代替:

var firstphs = xliff.Descendants() 
        .Elements(xmlns + "trans-unit") 
        .Elements(xmlns + "seg-source") 
        .Elements(xmlns+ "mrk") 
        .Where(e => e.Attribute("mtype").Value == "seg") 
        .Select(e => e.Elements(xmlns+"x").Select(x => (string)x.Attribute("id")).FirstOrDefault()) 
        .ToArray(); 

一般有用的提示:或者避免使用Value财产的情况下,元素属性可能不存在。相反,将元素或属性转换为string,如上面的代码片段所示。

+0

完美!我知道一个'选择'失踪...非常感谢! – ib11

0

如果您正在使用C#6,你可以这样做:

var firstphs = xliff.Descendants() 
        .Elements(xmlns + "trans-unit") 
        .Elements(xmlns + "seg-source") 
        .Elements(xmlns+ "mrk") 
        .Where(e => e.Attribute("mtype").Value == "seg") 
        .Select(e => e.Elements(xmlns+"x").FirstOrDefault()?.Attribute("id").Value ?? "") 
        .ToArray(); 

FirstOrDefault()?.。它被称为“空传播运算符”,只要左边的表达式为null,它就会返回null。如果不是,它将继续评估表达式。

+0

不幸的是,这给了我一个编译器错误的列表。 (我正在使用Microsoft Visual C#2013)。 – ib11

+0

C#6在Visual Studio 2015及更高版本中受支持 –