【问题标题】:Replace third octets of multiple IP addresses替换多个 IP 地址的第三个八位字节
【发布时间】:2020-10-17 23:54:26
【问题描述】:

我有两个输入 XML 文件,这是第一个:

<?xml version="1.0" encoding="utf-8"?>
<ipaddresses>
<ip>192.168.45.12</ip>
<ip>192.168.45.33</ip>
<ip>192.168.45.54</ip>
<ip>192.168.45.95</ip>
</ipaddresses>

第二个:

<ipaddresses>
    <ip>192.168.15.12</ip>
    <ip>192.168.25.13</ip>
    <ip>192.168.35.14</ip>
    <ip>192.168.45.15</ip>
</ipaddresses>

我想要的输出是:

<ipaddresses>
<ip>192.168.15.12</ip>
<ip>192.168.25.33</ip>
<ip>192.168.35.54</ip>
<ip>192.168.45.95</ip>
</ipaddresses>

简而言之,我想用第二个输入文件的第三个八位字节替换第一个输入文件的第三个八位位组。

目前我写的代码是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Xml.Linq;

namespace IPModifier
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument ipAddressesToModify = XDocument.Load(args[0]);
            XDocument sourceIPs = XDocument.Load(args[1]);
            List<XElement> ipAddresses = new List<XElement>();
            List<XElement> sourceIPAddresses = new List<XElement>();
            List<byte> utilizedOctets = new List<byte>();
            List<byte[]> ips = new List<byte[]>();

            IEnumerable<XElement> allIPs = from ipAddress in ipAddressesToModify.Root.Elements()
                                           select ipAddress;
            foreach (XElement ipAddress in allIPs)
            {
                ipAddresses.Add(ipAddress);
                Console.WriteLine(ipAddress.Value);
            }

            IEnumerable<byte> ipThirdOctets = from ipOctet in ipAddresses
                                              let byteOctetsThree = IPAddress.Parse(ipOctet.Value).GetAddressBytes()[2]
                                              select byteOctetsThree;
            foreach (byte octetOfIP in ipThirdOctets)
            {
                Console.WriteLine(octetOfIP.ToString());
            }

            IEnumerable<XElement> allsourceIP = from source in sourceIPs.Root.Elements()
                                                select source;

            foreach (XElement sourceIP in allsourceIP)
            {
                sourceIPAddresses.Add(sourceIP);
                Console.WriteLine(sourceIP.Value);
            }

            IEnumerable<byte> sourceOctets = from sourceIP in allsourceIP
                                             let octets = IPAddress.Parse(sourceIP.Value).GetAddressBytes()[2]
                                             select octets;
            foreach (byte octet in sourceOctets)
            {
                utilizedOctets.Add(octet);
                Console.WriteLine(octet);
            }

            foreach (XElement ipAdd in ipAddresses)
            {
                byte[] ip = IPAddress.Parse(ipAdd.Value).GetAddressBytes();
                ips.Add(ip);
            }


            foreach (byte[] ipToModify in ips)
            {
                foreach (byte oct in utilizedOctets)
                {


                    ipToModify[2] = oct;
                    IPAddress newIP = new IPAddress(ipToModify).MapToIPv4();

                    Console.WriteLine(newIP.ToString());
                }

            }

        }
    }
}

我尝试使用嵌套循环来解决这个问题,但是我得到了错误的输出,将第二个输入 XML 文件中的最后一个八位字节替换为“45”。问题是发生了太多的迭代。如果有人可以提供帮助,将不胜感激,我是 C# 的新手,主要来自 Java 经验。

【问题讨论】:

    标签: c# xml ip-address


    【解决方案1】:
    XDocument first = XDocument.Load(args[0]);
    XDocument second = XDocument.Load(args[1]);
     
    var result = new XElement(
        "ipaddresses",
        first.Root.Elements("ip")
            .Zip(second.Root.Elements("ip"),
                (f, s) => {
                    var first_bytes = IPAddress.Parse(f.Value).GetAddressBytes();
                    var second_bytes = IPAddress.Parse(s.Value).GetAddressBytes();
    
                    first_bytes[2] = second_bytes[2];
                    return new IPAddress(first_bytes);
                }
            )
            .Select(i => new XElement("ip", i.ToString()))
    );
    

    【讨论】:

      【解决方案2】:

      我创建了一个类并使用了 Xml Linq:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Xml;
      using System.Xml.Linq;
      
      namespace ConsoleApplication1
      {
          class Program
          {
              static void Main(string[] args)
              {
                  string xml1 = @"<?xml version=""1.0"" encoding=""utf-8""?>
                                      <ipaddresses>
                                      <ip>192.168.45.12</ip>
                                      <ip>192.168.45.33</ip>
                                      <ip>192.168.45.54</ip>
                                      <ip>192.168.45.95</ip>
                                      </ipaddresses>
                                      ";
                  XDocument doc1 = XDocument.Parse(xml1);
                  string xml2 = @"<?xml version=""1.0"" encoding=""utf-8""?>
                                       <ipaddresses>
                                          <ip>192.168.15.12</ip>
                                          <ip>192.168.25.13</ip>
                                          <ip>192.168.35.14</ip>
                                          <ip>192.168.45.15</ip>
                                      </ipaddresses>
                                      ";
                  XDocument doc2 = XDocument.Parse(xml2);
                  IP.Merge(doc1, doc2);
              }
          }
          public class IP
          {
              public string[] octets { get; set; }
              public XElement xIP { get; set; }
      
              public IP(XElement ip)
              {
                  xIP = ip;
                  octets = ((string)ip).Split(new char[] { '.' }).ToArray();
              }
               public void ReplaceOctet(int i, string[] octets2)
              {
                  octets[i] = octets2[i];
                  xIP.SetValue(string.Join(".", octets));
              }
              public static void Merge(XDocument doc1, XDocument doc2)
              {
                  List<IP> ip1 = doc1.Descendants("ip").Select(x => new IP(x)).ToList();
                  List<IP> ip2 = doc2.Descendants("ip").Select(x => new IP(x)).ToList();
      
                  for (int i = 0; i < ip1.Count(); i++)
                  {
                      ip1[i].ReplaceOctet(2, ip2[i].octets);
                  }
              }
          }
      }
      

      【讨论】:

      • 如何调用ReplaceOctet作为扩展方法?
      • @UweKeim 我认为不是扩展方法,但它是 IP 类中的一种方法,ip1[i] 是此类 new IP(x) 的实例化。所以你可以这样称呼它。
      • 代码正在设置 XElement 的新值,因此无需返回任何内容。设置一个新值会更改 XDocment 值并返回任何值。这些方法是类的实例。
      【解决方案3】:

      DataSet 可以读取 XML、推断架构并创建易于操作的表格表示:

              DataSet ip1 = new DataSet();       //a DataSet is a collection of DataTable
              ip1.ReadXml(@"c:\temp\ip1.xml");   //this will read the xml file and create a table named "ip" with a column "ip_Text"
              DataSet ip2 = new DataSet(); 
              ip2.ReadXml(@"c:\temp\ip2.xml");
      
              var r1 = ip1.Tables[0].Rows;       //could say Tables["ip"] or Tables[0] 
              var r2 = ip2.Tables[0].Rows;       //because there is only one table in the set
                                                 //.Rows is a collection of DataRow, a bit like a 2D array
      
              for (int i = 0; i < r1.Count; i++) { //iterate the rows in the collection
                  var a = r1[i][0].ToString().Split('.');    //2D array, indexed by i (the row) and 0 (the first column)
                  a[2] = r2[i][0].ToString().Split('.')[2];  //could also say [i]["ip_Text"]
                  r1[i][0] = string.Join(".", a);            //combine our edited array back to string and update the row
              }
              ip1.WriteXml(@"c:\temp\ip3.xml");              //write the rows back to xml
      

      在处理数据集和表格时,一个方便的技巧是在加载数据集后在 IDE 中设置断点(单击行号左侧,使其获得红点),然后运行程序。当它停止时,指向数据集变量并等待工具提示。它包含一个放大镜:

      单击放大镜会出现一个窗口,您可以使用它来查看网格中的数据:

      这对于了解列的索引或名称等非常有用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-02
        • 2018-09-19
        • 2014-05-13
        • 2013-10-26
        • 2018-12-01
        • 2021-08-26
        相关资源
        最近更新 更多