C# 仅当给定父元素下存在某个元素时才解析xml文件

C# 仅当给定父元素下存在某个元素时才解析xml文件,c#,xml,linq,C#,Xml,Linq,很抱歉,如果格式不正确,这是我的第一篇文章 我正在使用ASP.NET和C创建一个网站,以解析XML文件,转换某些元素值并附加到任意字符串。我遇到的问题是,XML文件中有一些接口元素不包含已启用的子元素,如果虚拟接口也不存在该子元素,则该子元素将是物理元素 如果这个子体不存在,我不想执行XML文件中的选择,您可以看到,我已经使用了where子句,但到目前为止已经删除了。下面粘贴了一个示例XML文件的一部分,显示了我所说的区别。非常感谢您的建议 谢谢你抽出时间 //Get and translate

很抱歉,如果格式不正确,这是我的第一篇文章

我正在使用ASP.NET和C创建一个网站,以解析XML文件,转换某些元素值并附加到任意字符串。我遇到的问题是,XML文件中有一些接口元素不包含已启用的子元素,如果虚拟接口也不存在该子元素,则该子元素将是物理元素

如果这个子体不存在,我不想执行XML文件中的选择,您可以看到,我已经使用了where子句,但到目前为止已经删除了。下面粘贴了一个示例XML文件的一部分,显示了我所说的区别。非常感谢您的建议

谢谢你抽出时间

//Get and translate interface configs
var interfaces = CurrentXML
                 .Descendants("interface-list")
                 .Elements("interface")
                 .Select(i => new { NAMEIF = i.Element("name").Value ,
                                    DESC   = i.Element("description").Value ,
                                    NOSHUT = i.Element("if-item-list")
                                              .Element("item")
                                              .Element("physical-if")
                                              .Element("enabled")
                                              .Value
                                  }
                   ) ;

//Build ASA Configuration and display to user.
ASAconfig.Append( "<br />" + deviceconf.HOSTNAME.ToString() ) ;

foreach ( var el in interfaces )
{
  ASAconfig.Append(
    string.Format("<br />nameif {0}<br /> description {1}<br /> {2}" ,
      el.NAMEIF != null ? el.NAMEIF.ToString() : string.Empty ,
      el.DESC   != null ? el.DESC.ToString()   : string.Empty ,
      el.NOSHUT.ToString() == "1" ? "no shut"  : string.Empty
      )
    ) ;
}
尝试将此添加到以下位置:

<interface>
  <name>SSL-VPN</name>
  <description>SSL VPN</description>
  <property>2</property>
  <if-item-list>
    <item>
      <item-type>5</item-type>
      <sslvpn>SSL-VPN</sslvpn>
    </item>
  </if-item-list>
</interface>
<interface>
  <name>DMZ</name>
  <description>DMZ</description>
  <property>0</property>
  <if-item-list>
    <item>
      <item-type>1</item-type>
      <physical-if>
        <if-num>2</if-num>
        <enabled>1</enabled>
        <if-property>3</if-property>
        <ip>10.21.2.1</ip>
        <netmask>255.255.0.0</netmask>
        <mtu>1500</mtu>
        <auto-negotiation>1</auto-negotiation>
        <link-speed>100</link-speed>
        <mac-address-enable>0</mac-address-enable>
        <mac-address />
        <full-duplex>1</full-duplex>
        <secondary-ip-list />
        <anti-spoof>2</anti-spoof>
        <anti-scan>0</anti-scan>
        <block-notification>0</block-notification>
        <dos-prevention>1</dos-prevention>
        <intra-inspection>0</intra-inspection>
        <dhcp-server>
          <server-type>0</server-type>
        </dhcp-server>
        <vpn-df-bit>0</vpn-df-bit>
        <qos>
          <max-link-bandwidth>0</max-link-bandwidth>
          <qos-marking>
            <marking-field>2</marking-field>
            <marking-method>
              <marking-type>0</marking-type>
            </marking-method>
            <priority-method>0</priority-method>
          </qos-marking>
        </qos>
        <static-mac-ip-binds>
          <restrict-traffic>0</restrict-traffic>
        </static-mac-ip-binds>
        <static-mac-acl>
          <enable>0</enable>
        </static-mac-acl>
      </physical-if>
    </item>
  </if-item-list>
...

Linq没有什么神奇之处,除了它是目前流行的银色子弹。在我看来,如果您使用XPath来选择元素集,那么您想要做的事情会更容易、更清晰

使用XPath,它非常简单:

.Elements("interface")
.Where(i => null != i.Descendants("enabled").FirstOrDefault())
.Select // ...
应该注意的是,XmlNodeList是IEnumerable而不是IEnumerable,因此要执行任何类型的Linq魔术,您需要像这样对其进行转换:

XmlDocument xmldoc = new XmlDocument() ;
xmldoc.LoadXml(rawXml) ; // load your XML string here

XmlNodeList selectedNodes = xmldoc.SelectNodes( "/interface-list/interface[if-item-list/item/physical-if/enabled]" ) ;

所以你们只需要包含元素的元素?
selectedNodes
.Cast<XmlNode>()
.Select( ... )
;