3

そこにない可能性のあるサブツリーの下にある xml タグの値を取得しようとすると、nullexception の問題が発生します。

拡張ハンドラは、既存のサブツリーでタグが見つからない場合はうまく機能しますが、存在しないサブツリーでタグを探す場合は処理できないようです。

この場合、サブツリーは summaryData であり、そこにある場合とない場合があり、addressLine1 を取得しようとすると、null.

System.NullReferenceException が発生しました。メッセージ = オブジェクト参照がオブジェクトのインスタンスに設定されていません。

これが xml です。わかりやすくするために省略されていますが、構造は正しいです。

 <record>
  <accounts>
    <account >
    </account >
  </accounts>
  <summaryData>
    <Date>2013-02-04</Date>
    <address >
      <city>Little Rock</city>
      <postalCode>00000</postalCode>
      <state>AR</state>
      <addressLine1>Frank St</addressLine1>
    </serviceAddress>
  </summaryData>

</record>

私のC#コードは次のとおりです。

 xmlDoc.Descendants("account")
                //select (string)c.Element("account") ;
                select new
                {
                    //this works fine
                    Stuffinxml = c.Element("stuffinxml").Value,
                    //this field may not be there, but the handler handlers the exception correctly here when it as the correct root (account)
                    otherstuff = CustXmlHelp.GetElementValue(mR.Element("otherstuff")),
                    //this is the problem, where the summaryData root does not exist (or moved somewhere else)
                    street_address = GetElementValue(c.Element("summaryData").Element("serviceAddress").Element("addressLine1"))

                };

null を処理するための私の拡張メソッドは次のとおりです。

 public static string GetElementValue(this XElement element)
    {
        if (element != null)
        {
            return element.Value;
        }
        else
        {
            return string.Empty;
        }
    }

サブツリーが存在しないときに失敗する理由がわからないので、助けていただければ幸いです。

4

3 に答える 3

2

要約データが存在する場合と存在しない場合があります

それが理由です。呼び出しをネストしているため、それらすべてを null チェックする必要があります。

これらのいずれかが null になる可能性があります。

c.Element("summaryData").Element("serviceAddress").Element("addressLine1")

複雑な条件がなければ、それを回避する良い方法はありません:

street_address = c.Element("summaryData") != null
    ? c.Element("summaryData").Element("serviceAddress") != null
        ? GetElementValue(c.Element("summaryData").Element("serviceAddress").Element("addressLine1"))
        : string.Empty
    : string.Empty;
于 2013-02-28T14:36:20.887 に答える
1

すでに述べたように、例外は複数のネストされたクエリを渡しているという事実によるものです

c.Element("summaryData").Element("serviceAddress").Element("addressLine1")

書くことと同等です:

var x1 = c.Element("summaryData");
var x2 = x1.Element("serviceAddress")
var x3 = x2.Element("addressLine1")

したがって、、、またはのいずれcx1x2nullの場合、。を取得しNullReferenceExceptionます。

LINQ複数のnullチェックを使用する純粋なソリューションの1つの可能な代替手段はXPath、式を作成するために使用することです。

を使用XPathすると、すべてのレベルでnullチェックを実行するのではなく、代わりに式を記述できます。

street_address = GetElementValue(c.XPathSelectElement("/summaryData/serviceAddress/addressLine1"))

これにより、式全体が評価され、式全体が存在しない場合はが返さnullれますが、純粋なLINQクエリのように例外はスローされません。

于 2013-03-01T00:45:39.223 に答える
1

summaryDate要素が存在しない場合

c.Element("summaryData").Element("serviceAddress").Element("addressLine1")

null 参照 ( )NullReferenceExceptionを呼び出そうとしているため、 a がスローされます。Element()c.Element("summaryData")

于 2013-02-28T14:34:31.053 に答える