2016-04-28 11 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以降でサポートされています –

関連する問題