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