Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 仅当给定属性至少不存在一次或包含给定值时才加载XML_C#_Asp.net_Xml - Fatal编程技术网

C# 仅当给定属性至少不存在一次或包含给定值时才加载XML

C# 仅当给定属性至少不存在一次或包含给定值时才加载XML,c#,asp.net,xml,C#,Asp.net,Xml,假设我有一个xml,我想使用.net(C#)验证此文件,以验证是否如下所示: 如果至少有一个文件节点没有筛选器,请执行某些操作 如果所有文件都有过滤器属性,并且至少有一个 匹配筛选器值以执行某些操作 如果以上两项都不满足,则什么也不做 正如预期的那样,我一直在努力工作,并提出了非常复杂的代码,我相信这可以像我尝试的那样简单 一些示例:接受的筛选器值将为“nl” <!-- some nodes above --> <file name="something"/> <

假设我有一个xml,我想使用.net(C#)验证此文件,以验证是否如下所示:

  • 如果至少有一个文件节点没有筛选器,请执行某些操作
  • 如果所有文件都有过滤器属性,并且至少有一个 匹配筛选器值以执行某些操作
  • 如果以上两项都不满足,则什么也不做
正如预期的那样,我一直在努力工作,并提出了非常复杂的代码,我相信这可以像我尝试的那样简单

一些示例:接受的筛选器值将为“nl”

<!-- some nodes above -->
<file name="something"/>
<file name="something else"/>
<file name="and something else" filter="en, fr, de"/>
<!-- more nodes below -->

当至少有一个文件没有筛选值时,这将通过

<!-- some nodes above -->
<file name="something" filter="nl, hu"/>
<file name="something else" filter="ru"/>
<file name="and something else" filter="en, fr, de"/>
<!-- more nodes below -->

这也会通过,因为至少有一个文件符合“nl”限制(第一个文件)


这一个应该失败,因为两个文件都不缺少filter属性,并且两个筛选器都不包含“nl”


关于实现这一点最简单、最有效的方法有什么建议吗?

您只需使用您选择的方法(XmlReader、Linq to Xml、XmlDocument)通过Xml文件即可。如果您发现一个文件不包含筛选器或与您的条件匹配的筛选器,则该文件将进行验证。否则它就不会


最有效的方法当然是使用普通的XmlReader,因为这种方法不会将Xml保存在内存中。其他方法也在内部使用XmlReader,但更方便。

您尝试过linq2xml吗

XDocument doc = XDocument.Load(@"data.xml");

var restrict = "nl";
var anyMissingFilter = (from filter in doc.Descendants("file")
                         where filter.Attribute("filter") == null
                         select 1).Any();
var anyRestrictionMatch = (from filter in doc.Descendants("file")
                           where 
                               filter.Attribute("filter") != null &&
                               filter.Attribute("filter").Value.Contains(restrict)
                           select 1).Any();

除非要检查大量节点(即数千个),否则我非常喜欢使用
XmlSerializer
将完整的XML数据读入内存中的数据对象模型。然后,您可以使用任何内置的C代码/逻辑来过滤数据。除非您在执行此操作时遇到特定的性能问题,否则我认为它是最简单、最易于维护的。(好处:如果您的程序中有用户在编辑您的文件筛选器,您可以使用相同的逻辑来验证它们)编辑:Bonus2:它分离了您的序列化问题,使添加/更改筛选器更容易,或者更好地跟踪/报告或单元测试问题。我还没有真正研究过这一点。事实上,我正在刷新我的知识,因为我被困了几年,仍然在将我的.net 1 VB技能转换为最新的C#,有时可能会有点挑战。。。这看起来很有希望,至少,我想我只需要做一个检查,如果任何MissingFilter或任何RestrictionMatch包含我可以安全访问的内容,它们都是bool;Any()方法只在达到第一个匹配条件时返回true。太好了,我实际上设法将它放在一个块中,如下所示:var validNodes=(来自doc.substands(“file”)中的文件,其中files.Attribute(“locales”)==null | | files.Attribute(“locales”).Value.Contains(locale)select 1.Any();如果(validNodes==true){rest of code}像一个符咒一样工作,谢谢!按照Georg的观点,如果您有一个大文档,或者需要尽可能多的性能,那么您将需要一种流媒体方法。这个方法将从整个XML树中创建一个文档。文件非常小(约100k),因此此方法应该可以正常工作。我也会潜入流媒体,但这一个让我现在已经摆脱了麻烦
XDocument doc = XDocument.Load(@"data.xml");

var restrict = "nl";
var anyMissingFilter = (from filter in doc.Descendants("file")
                         where filter.Attribute("filter") == null
                         select 1).Any();
var anyRestrictionMatch = (from filter in doc.Descendants("file")
                           where 
                               filter.Attribute("filter") != null &&
                               filter.Attribute("filter").Value.Contains(restrict)
                           select 1).Any();