web-dev-qa-db-ja.com

C#Linq to XMLは、要素が存在するかどうかを確認します

私は次のようなXMLドキュメントを持っています:

<Database>
 <SMS>
   <Number>"+447528349828"</Number> 
   <Date>"09/06/24</Date> 
   <Time>13:35:01"</Time> 
   <Message>"Stop"</Message> 
 </SMS>
 <SMS>
   <Number>"+447528349828"</Number> 
   <Date>"09/06/24</Date> 
   <Time>13:35:01"</Time> 
   <Message>"Stop"</Message> 
 </SMS>
</Database>

親の子ノードの番号SMSノードがドキュメントに存在するかどうかを確認しようとしています(重複データの挿入を回避するための検証目的で)。

考えられる解決策について何かアドバイスはありますか?

編集:要素は入力文字列と比較されます。たとえば、if(inputNumber == xmlDocNumber){//新しい要素を挿入しないでください}

25
Goober

Count()を使用するのとは少し異なる方法を提案します-Any()を使用します。利点は、Any()が一致するものを取得するとすぐに停止できることです。

_var smsWithNoNumber = main.Descendants("SMS")
                          .Where(x => !x.Elements("Number").Any());
_

この場合、それほど確率は高くありませんが、Count()が少なくとも1つあったことを通知するためだけに、100万ヒットをカウントする必要がある場合は、知っておくと便利です。それはあなたが何を意味するのかをより明確に示すものでもあると思います。

43
Jon Skeet

正規化された形式の番号があり、XMLがXmlDocumentなどにロードされているとすると、LINQ以外の最も簡単な方法はXPathクエリを使用することです。

string pattern = String.Format("/Database/SMS/Number[. = '{0}']", number);
if (myDoc.SelectSingleNode(pattern) != null)
{
   // number already exists in document
}
2
Robert Rossney

SMSノードをループし、Number/text()値が重複しているノードを除外することで、データを変換するXSLドキュメントを適用できます。

チェックは次のようになります。

<xsl:template match="SMS">
<xsl:variable name="parentNode" select="." />
<xsl:if test="preceding-sibling::SMS/Number/text()=$parentNode/Number/text()">
.....include a copy of node......
</xsl:if>
  </xsl:template>
0
Jay