2012-01-08 3 views
2

Если у меня есть файл XML, и я хочу, чтобы проверить уникальность атрибута id каждого элемента, как следующий документ:Как проверить уникальность атрибута в файле XML

<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 хотите, чтобы атрибут id был уникальным.

ответ

1

Вы можете использовать HashSet для проверки уникальности.

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"); 
1

В коде или что? Вы всегда можете добавить XML-схему или DTD и проверить правильность (вы можете определить, что attr будет уникальным).

т. Е. Написать XMLScheme или DTD (DTD проще, но менее гибко), чтобы определить структуру вашего XML. Определите там, что атрибут id тега class уникален (это ID в DTD). В коде, проверьте данный XML является действительным в отношении XML Sheme/DTD

Tuts для XML-схем Unique и ОТД ID:

XML XSD Schema - Enforce Unique Attribute Values in Schema

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

и поиск для проверки XML в коде.

+0

да в коде .. –

+0

Мог ли дать мне пример или ссылку на то, что вы хотите сказать? –

+0

см. Редактирование. Кстати, 'colums' в' классах 'кажется чрезмерным и неправильным для меня. Определение тегов атрибутов - это структура документа, а не данные - она ​​должна быть в схеме/dtd, а не в родительском элементе. –

3

Предполагая, что вы не можете добавить его в схему, можно использовать LINQ к XML для этого:

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(); 
+0

hmmm, большое спасибо. Это для одного элемента или для всех элементов: xml-файл вот так: –

+1

@just_name: Это весь документ - это то, что делает вызов потомков. –

+0

Большое спасибо ... –

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); 
1

этот XPath возвращает логическое значение, указывающее, является ли или нет повторяются значения: @id

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

с нанесенным на нее XPathEvaluate method:

XDocument d = XDocument.Parse(xml); 
bool hasDuplicateId = (bool)d.XPathEvaluate("boolean(//*/@id[.=following::*/@id])"); 
Смежные вопросы