25

I have an XML document as follows:

<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>

I am trying to check whether the number child node of the parent SMS node exists in the document (for validation purposes to avoid inserting duplicate data).

Any advice on a potential solution?

EDIT: The element will be compared to an input string. For example if(inputNumber == xmlDocNumber){ //Don't Insert New Element }

Goober
  • 13,146
  • 50
  • 126
  • 195
  • Could you give us some sample (pseudo?) code to provide context and clearer picture of you needs> – John Fisher Jun 24 '09 at 17:13
  • 1
    how would sample code help..........find any specified element in an xml document.......what could i possibly give you besides what i have? – Goober Jun 29 '09 at 15:26

3 Answers3

44

I'll suggest a slightly different tack to using Count() - use Any(). The advantage is that Any() can stop as soon as it gets any matches at all:

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

In this case it won't make much odds, but in cases where Count() might have to count a million hits just to tell you that there was at least one, it's a useful trick to know. I'd say it's also a clearer indicator of what you mean.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • How do I use this for checking? Sorry, I'm still in the process of getting familiar with LINQ – Blackator Sep 05 '12 at 06:19
  • @Blackator: The `Any` part is *doing* the check. I don't know what problem you're facing, so it's hard to be more precise. Perhaps you should be asking a new question? – Jon Skeet Sep 05 '12 at 06:21
  • Please check my question [here](http://stackoverflow.com/questions/12276533/check-if-an-element-exists-in-xml). Thanks Jon – Blackator Sep 05 '12 at 07:31
2

Assuming that you have your number in some canonicalized form and your XML is loaded into an XmlDocument or some such, the simplest non-LINQ way to do it is with an XPath query:

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

You could apply an XSL document that translates the data by looping through the SMS nodes and excluding any that has a duplicate Number/text() value

Check would be something like:

<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>
Jay
  • 2,644
  • 1
  • 30
  • 55