如何检查 XML 中是不是存在特定属性?

Posted

技术标签:

【中文标题】如何检查 XML 中是不是存在特定属性?【英文标题】:How do I check particular attributes exist or not in XML?如何检查 XML 中是否存在特定属性? 【发布时间】:2011-11-03 10:44:27 【问题描述】:

部分XML内容:

<section name="Header">
  <placeholder name="HeaderPane"></placeholder>
</section>

<section name="Middle" split="20">
  <placeholder name="ContentLeft" ></placeholder>
  <placeholder name="ContentMiddle"></placeholder>
  <placeholder name="ContentRight"></placeholder>
</section>

<section name="Bottom">
  <placeholder name="BottomPane"></placeholder>
</section>

我想检查每个节点,如果属性split存在,尝试在变量中分配一个属性值。

在一个循环中,我尝试:

foreach (XmlNode xNode in nodeListName)

    if(xNode.ParentNode.Attributes["split"].Value != "")
    
        parentSplit = xNode.ParentNode.Attributes["split"].Value;
    

但是如果条件只检查值而不检查属性的存在,那我就错了。我应该如何检查属性是否存在?

【问题讨论】:

虽然在问这个问题时这可能不是真的,但现在有一个XmlElement.HasAttribute Method,对我来说,它似乎非常适合这种用例。以防万一有人偶然发现这个...... 【参考方案1】:

您实际上可以直接索引到 Attributes 集合中(如果您使用的是 C# 而不是 VB):

foreach (XmlNode xNode in nodeListName)

  XmlNode parent = xNode.ParentNode;
  if (parent.Attributes != null
     && parent.Attributes["split"] != null)
  
     parentSplit = parent.Attributes["split"].Value;
  

【讨论】:

如果节点的属性为零,则抛出异常。您需要首先测试 Attributes 集合不为空。 我猜是新的语法糖:if (parent?.Attributes["split"] != null) 我觉得更像if (parent.Attributes?["name"] != null)【参考方案2】:

如果您的代码正在处理XmlElements 对象(而不是XmlNodes),则有XmlElement.HasAttribute(string name) 方法。

因此,如果您只是在元素上查找属性(从 OP 中看起来),那么将其强制转换为元素,检查 null,然后使用 HasAttribute 方法可能会更可靠。

foreach (XmlNode xNode in nodeListName)

  XmlElement xParentEle = xNode.ParentNode as XmlElement;
  if((xParentEle != null) && xParentEle.HasAttribute("split"))
  
     parentSplit = xParentEle.Attributes["split"].Value;
  

【讨论】:

【参考方案3】:

仅适用于新手:最新版本的 C# 允许使用 ? 运算符来检查空值分配

parentSplit = xNode.ParentNode.Attributes["split"]?.Value;

【讨论】:

【参考方案4】:

您可以使用 LINQ to XML,

XDocument doc = XDocument.Load(file);

var result = (from ele in doc.Descendants("section")
              select ele).ToList();

foreach (var t in result)

    if (t.Attributes("split").Count() != 0)
    
        // Exist
    

    // Suggestion from @UrbanEsc
    if(t.Attributes("split").Any())
    

    

 XDocument doc = XDocument.Load(file);

 var result = (from ele in doc.Descendants("section").Attributes("split")
               select ele).ToList();

 foreach (var t in result)
 
     // Response.Write("<br/>" +  t.Value);
 

【讨论】:

+1 用于 Linq to XML。而不是 Count() != 0 你可以使用 Any() @UrbanEsc - 只是出于好奇,使用 Any() 而不是 Count() 有什么好处吗? 查看这个 SO 主题 ***.com/questions/305092/…【参考方案5】:
var splitEle = xn.Attributes["split"];

if (splitEle !=null)
    return splitEle .Value;

【讨论】:

【参考方案6】:

编辑

忽略 - 您不能使用 ItemOf (这是我在测试之前输入的内容)。如果我能弄清楚怎么做,我会删除文本……或者我会简单地删除答案,因为它最终是错误的和无用的。

结束编辑

您可以使用 XmlAttributesCollection 中的ItemOf(string) 属性来查看该属性是否存在。如果未找到,则返回 null。

foreach (XmlNode xNode in nodeListName)

    if (xNode.ParentNode.Attributes.ItemOf["split"] != null)
    
         parentSplit = xNode.ParentNode.Attributes["split"].Value;
    

XmlAttributeCollection.ItemOf Property (String)

【讨论】:

我的意思是检查属性split 存在。如果属性存在,则在变量中分配属性值。谢谢。 @Shree - 上面的代码将检查属性“split”是否存在,如果存在,如果将属性的值分配给parentSplit。请注意,如果 nodeListName 中有多个 XmlNode 的 ParentNode 具有“split”属性,则列表中的最后一个将分配给 parentSplit,覆盖之前的(如果有的话)。 ItemOf 实际上是指向 Attribute 集合的直接索引。 ItemOf 是与此交互的 VB 方式。直接索引到集合中是 C# 方法。【参考方案7】:

您可以使用 GetNamedItem 方法来检查该属性是否可用。如果返回 null,则它不可用。这是您进行该检查的代码:

foreach (XmlNode xNode in nodeListName)

    if(xNode.ParentNode.Attributes.GetNamedItem("split") != null )
    
        if(xNode.ParentNode.Attributes["split"].Value != "")
        
            parentSplit = xNode.ParentNode.Attributes["split"].Value;
        
      

【讨论】:

正如其他人在这里提到的,在继续之前检查 xNode.ParentNode.Attributes 是否为空总是好的。【参考方案8】:

处理这种情况的另一种方法是异常处理。

每次调用不存在的值时,您的代码都会从异常中恢复并继续循环。在 catch 块中,当表达式 (... != null) 返回 false 时,您可以像在 else 语句中写下错误一样处理错误。当然,抛出和处理异常是一项相对昂贵的操作,根据性能要求可能并不理想。

【讨论】:

以上是关于如何检查 XML 中是不是存在特定属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过批处理文件命令检查 xml 元素/属性是不是存在

检查是不是存在节点并检查其属性值

如何快速检查对象数组中是不是存在属性值

XML解析检查属性是不是存在

检查xml父节点中是不是存在两个xml节点

如何检查哈希中是不是存在特定键?