2

If I have an XML file and I want to check the uniqueness of the attribute id of each element like the following document:

<classes columns="id,name,short,classroomids,teacherid,grade,customfield1">
  <class id="0ini" name="Initial Class" short="Init" teacherid="" classroomids="" grade="" customfield1="0"/>
  <class id="*2" name="A1" short="A1" teacherid="" classroomids="" grade="" customfield1="30"/>
  <class id="*3" name="A2" short="A2" teacherid="" classroomids="" grade="" customfield1=""/>
</classes>

I want to check that the id attribute is unique.

Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
Anyname Donotcare
  • 11,113
  • 66
  • 219
  • 392

5 Answers5

3

Assuming you can't add it to the schema, you could use LINQ to XML for that:

var allIds = doc.Descendants()
                .Select(x => x.Attribute("id"))
                .Where(x => x != null)
                .Select(x => x.Value)
                .ToList();
var allDistinct = allIds.Count == allIds.Distinct().Count();
svick
  • 236,525
  • 50
  • 385
  • 514
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

In code or what? You could always add XML Scheme or DTD and check validity (you can define attr to be unique).

i.e. write XMLScheme or DTD (DTD is simpler, but less flexible), to define structure of your XML. Define there that attribute id of tag class is unique (is ID in DTD). In code, check if given XML is valid against XML Sheme / DTD

Tuts for XML Schemas Unique and DTDs ID:

XML XSD Schema - Enforce Unique Attribute Values in Schema

http://www.featureblend.com/dtd-unique-attribute.html

and search for validating xml in code.

Community
  • 1
  • 1
Adam Jurczyk
  • 2,153
  • 12
  • 16
1

You can use a HashSet to check for uniqueness.

var set = new HashSet<string>();
foreach(var id in doc.Descendants()
                 .Select(a => a.Attribute("id").Value))
  if(!set.Add(id))
    throw new Exception("Not Unique");
svick
  • 236,525
  • 50
  • 385
  • 514
Magnus
  • 45,362
  • 8
  • 80
  • 118
1
var data = XElement.Parse (@"
<classes columns='id,name,short,classroomids,teacherid,grade,customfield1'>
   <class id='0ini' name='Initial Class' short='Init' teacherid='' classroomids='' grade='' customfield1='0'/>
   <class id='*2' name='A1' short='A1' teacherid='' classroomids='' grade='' customfield1='30'/>
   <class id='*3' name='A2' short='A2' teacherid='' classroomids='' grade='' customfield1=''/>
</classes>");       

bool containsDuplicates = data.Descendants().GroupBy(desc=>desc.Attribute("id").Value).Any(grp=>grp.Count()>1);
Tormod
  • 4,551
  • 2
  • 28
  • 50
1

This XPath returns a boolean value indicating whether or not there are repeated @id values:

boolean(//*/@id[.=following::*/@id])

Applied with the XPathEvaluate method:

XDocument d = XDocument.Parse(xml);
bool hasDuplicateId = (bool)d.XPathEvaluate("boolean(//*/@id[.=following::*/@id])");
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147