Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.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# 如何使用linq从具有相同元素和属性的复杂xml中提取数据_C#_Xml Parsing_Linq To Xml - Fatal编程技术网

C# 如何使用linq从具有相同元素和属性的复杂xml中提取数据

C# 如何使用linq从具有相同元素和属性的复杂xml中提取数据,c#,xml-parsing,linq-to-xml,C#,Xml Parsing,Linq To Xml,这是我第一次使用LINQtoXML,我正在努力从xml文件中提取一些数据。 问题似乎是由于xml的格式化方式(这是我无法控制的),因为它具有相同的元素和属性 <host starttime="1357755777" endtime="1357755993"> <status state="up" reason="arp-response"/> <address addr="192.168.1.1" addrtype="ipv4"/> &

这是我第一次使用LINQtoXML,我正在努力从xml文件中提取一些数据。 问题似乎是由于xml的格式化方式(这是我无法控制的),因为它具有相同的元素和属性

<host starttime="1357755777" endtime="1357755993">
    <status state="up" reason="arp-response"/>
    <address addr="192.168.1.1" addrtype="ipv4"/>
    <address addr="00:50:56:90:77:9F" addrtype="mac" vendor="VMware"/>
    <hostnames>
        <hostname name="test1.test.com" type="PTR"/>
    </hostnames>
    <ports>
        <extraports state="closed" count="95">
            <extrareasons reason="resets" count="95"/>
        </extraports>
        <port protocol="tcp" portid="135">
            <state state="open" reason="syn-ack" reason_ttl="128"/>
            <service name="msrpc" product="Microsoft Windows RPC" ostype="Windows" method="probed" conf="10">
                <cpe>cpe:/o:microsoft:windows</cpe>
            </service>
        </port>
        <port protocol="tcp" portid="139">
            <state state="open" reason="syn-ack" reason_ttl="128"/>
            <service name="netbios-ssn" method="probed" conf="10"/>
        </port>
        <port protocol="tcp" portid="445">
            <state state="open" reason="syn-ack" reason_ttl="128"/>
            <service name="microsoft-ds" product="Microsoft Windows 2003 or 2008 microsoft-ds" ostype="Windows" method="probed" conf="10">
                <cpe>cpe:/o:microsoft:windows</cpe>
            </service>
        </port>
        <port protocol="tcp" portid="3389">
            <state state="open" reason="syn-ack" reason_ttl="128"/>
            <service name="ms-wbt-server" product="Microsoft Terminal Service" ostype="Windows" method="probed" conf="10"/>
        </port>
        <port protocol="tcp" portid="8081">
            <state state="open" reason="syn-ack" reason_ttl="128"/>
            <service name="http" product="Network Associates ePolicy Orchestrator" method="probed" conf="10"/>
        </port>
    </ports>
</host>
<host starttime="1357755777" endtime="1357755993">
    <status state="up" reason="arp-response"/>
    <address addr="192.168.1.2" addrtype="ipv4"/>
    <address addr="00:50:56:90:67:8F" addrtype="mac" vendor="VMware"/>
    <hostnames>
        <hostname name="test2.test.com" type="PTR"/>
    </hostnames>
    <ports>
        <extraports state="closed" count="97">
            <extrareasons reason="resets" count="97"/>
        </extraports>
        <port protocol="tcp" portid="53">
            <state state="open" reason="syn-ack" reason_ttl="64"/>
            <service name="domain" product="dnsmasq" version="2.33" method="probed" conf="10">
                <cpe>cpe:/a:thekelleys:dnsmasq:2.33</cpe>
            </service>
            <script id="dns-nsid" output="&#xa;  bind.version: dnsmasq-2.33&#xa;"/>
        </port>
        <port protocol="tcp" portid="81">
            <state state="open" reason="syn-ack" reason_ttl="64"/>
            <service name="http" product="Apache httpd" method="probed" conf="10">
                <cpe>cpe:/a:apache:http_server</cpe>
            </service>
            <script id="http-title" output="Did not follow redirect to https://192.168.100.14:445/ and no page was returned."/>
            <script id="http-favicon" output="Unknown favicon MD5: 95CDE3E49C5B2645F99AAAAABB6CD4C6"/>
            <script id="http-methods" output="No Allow or Public header in OPTIONS response (status code 403)"/>
        </port>
        <port protocol="tcp" portid="445">
            <state state="open" reason="syn-ack" reason_ttl="64"/>
            <service name="http" product="Apache httpd" method="probed" conf="10">
                <cpe>cpe:/a:apache:http_server</cpe>
            </service>
            <script id="http-title" output="400 Bad Request"/>
            <script id="http-methods" output="No Allow or Public header in OPTIONS response (status code 403)"/>
        </port>
    </ports>
</host>
我发现的每一篇教程都没有针对这种类型的XML进行讨论。 我可以得到每种类型的第一个条目,但不能得到第二个条目。 我还没有找到一种方法来遍历它们中的每一个。 我想要的是输出这个


status=up,ip=192.168.100.171,iptype=ipv4,port=22,port=80

您可以在原始选择中执行新选择。请参见答案中使用LINQ的示例:

foreach (XElement hostElement in NmapScan.Descendants("host"))
{
    // Gets the XElement "address" that have the attribute "addrtype" set to "mac"
    XElement macAddressElement = (from addressElement in hostElement.Elements("address")
                                    where addressElement.Attribute("addrtype").Value == "mac"
                                    select addressElement).Single();

    // Gets the XElement "address" that have the attribute "addrtype" set to "ipv4"
    XElement ipV4AdressElement = (from addressElement in hostElement.Elements("address")
                                    where addressElement.Attribute("addrtype").Value == "ipv4"
                                    select addressElement).Single();

    var p = new
    {
        status = hostElement.Element("status").Attribute("state").Value,
        addrIpv4 = ipV4AdressElement.Attribute("addr").Value,
        addrMac = macAddressElement.Attribute("addr").Value,
        addrVendor = macAddressElement.Attribute("vendor").Value,
        ports = (from portElement in hostElement.Element("ports").Elements("port")
                    select portElement.Attribute("portid").Value).ToList()
    };

    Console.WriteLine(p);
}

XML中缺少缩进和代码中的奇怪缩进都使阅读变得困难。优秀的Cedric,直到不久后尝试
foreach (XElement hostElement in NmapScan.Descendants("host"))
{
    // Gets the XElement "address" that have the attribute "addrtype" set to "mac"
    XElement macAddressElement = (from addressElement in hostElement.Elements("address")
                                    where addressElement.Attribute("addrtype").Value == "mac"
                                    select addressElement).Single();

    // Gets the XElement "address" that have the attribute "addrtype" set to "ipv4"
    XElement ipV4AdressElement = (from addressElement in hostElement.Elements("address")
                                    where addressElement.Attribute("addrtype").Value == "ipv4"
                                    select addressElement).Single();

    var p = new
    {
        status = hostElement.Element("status").Attribute("state").Value,
        addrIpv4 = ipV4AdressElement.Attribute("addr").Value,
        addrMac = macAddressElement.Attribute("addr").Value,
        addrVendor = macAddressElement.Attribute("vendor").Value,
        ports = (from portElement in hostElement.Element("ports").Elements("port")
                    select portElement.Attribute("portid").Value).ToList()
    };

    Console.WriteLine(p);
}