如果给定父元素下存在某个元素,则仅解析xml文件

时间:2014-01-10 19:53:23

标签: c# xml linq

//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
      )
    ) ;
}

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

我正在使用ASP.NET和C#创建一个网站来解析XML文件并转换某些元素值并附加到任意字符串。我遇到的问题是XML文件中有“interface”元素,它们不包含“enabled”后代(将是“physical-if”的元素,虚拟接口也不存在)。

如果这个后代不存在,我不想从XML文件中执行选择,并且你可以看到我使用了“where”子句但是到目前为止已经被淘汰了。下面粘贴了一个示例XML文件的一部分,显示了我正在谈论的差异。任何意见是极大的赞赏。

感谢您的时间。

<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>
...

2 个答案:

答案 0 :(得分:0)

尝试添加以下内容:

.Elements("interface")
.Where(i => null != i.Descendants("enabled").FirstOrDefault())
.Select // ...

答案 1 :(得分:0)

Linq没有任何神奇之处(除了它是当前的银弹 du jour 之外)。在我看来,如果您使用XPath选择元素集,那么您想要做的事情会更容易,也可能更清晰。

使用XPath,它很简单:

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

应该注意XmlNodeListIEnumerable而不是IEnumerable<T>,所以要做任何类型的Linq magick,你需要像这样投射:

selectedNodes
.Cast<XmlNode>()
.Select( ... )
;