2012-01-08 61 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> 

我要检查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 Scheme或DTD并检查有效性(您可以将attr定义为唯一的)。

即编写XMLScheme或DTD(DTD更简单但灵活性更低)来定义XML的结构。在那里定义标签class的属性id是唯一的(在DTD中是ID)。在代码中,检查是否给定的XML的XML模式Unique和DTD ID是对XML Sheme/DTD

TUTS有效:

XML XSD Schema - Enforce Unique Attribute Values in Schema

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

并搜索代码验证XML。

+0

耶在代码.. – 2012-01-08 12:09:41

+0

难道你能给我一个例子或者链接到你想说的吗? – 2012-01-08 12:10:28

+0

请参阅编辑。顺便说一下,'classes'中的'colums'对我来说似乎过分和错误。定义标签具有的属性是文档结构,而不是数据 - 它应该在schema/dtd中,而不是在父元素中。 – 2012-01-08 12:30:45

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

嗯,非常感谢。对于一个元素或所有元素: 这样的xml文件: – 2012-01-08 12:13:50

+1

@just_name:这是整个文档 - 这就是后代所称的。 – 2012-01-08 13:20:55

+0

非常感谢... – 2012-01-08 13:46:36

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