【问题标题】:Updating XML Files inside a directory更新目录中的 XML 文件
【发布时间】:2020-04-10 05:01:10
【问题描述】:

我仍然是 C# 的新手,但我创建了一个实用程序,如果出于某种原因他们的 IP 地址要更改或他们想要更改它,存储的 IP 地址将更新为当前 IP 地址。

我的代码应该过滤目录中的所有 xml 配置文件并使用新的 IP 地址更新它。然而,它们是某些文件夹中的一些 xml 配置文件,我不想像 net.tcp://localhost 那样更改它们。

<endpoint name="SessionLocal" address="net.tcp://localhost:7732/AuthenticationServices/Secure" binding="netTcpBinding" contract="Stuff.Services.ServiceContracts.IAuthenticationService" bindingConfiguration="TcpCustomSecurity" behaviorConfiguration="SecureBehaviorName">
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>
      <endpoint name="DataLocal" address="net.tcp://localhost:7732/DataServices/Secure" binding="netTcpBinding" contract="Stuff.Services.ServiceContracts.IDataService" bindingConfiguration="TcpCustomSecurity" behaviorConfiguration="SecureBehaviorName">
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>

接下来的几个文件夹包含我想要更改的具有实际 IP 地址的 xml 文件,例如

<endpoint name="SubscriptionLocal" address="net.tcp://10.249.30.4:7732/EventSubscriberServices/Secure" binding="netTcpBinding" contract="Stuff.Services.ServiceContracts.ISubscriptionService" bindingConfiguration="TcpCustomSecurity" behaviorConfiguration="CustomValidator">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <endpoint name="PublishLocal" address="net.tcp://10.249.30.4:7732/EventPublishServices/Secure" binding="netTcpBinding" contract="Stuff.Services.ServiceContracts.IPublishService" bindingConfiguration="TcpCustomSecurity" behaviorConfiguration="CustomValidator">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint> 

1) 我将如何添加代码,以便用户可以选择手动输入 IP 地址,以更新 xml 配置文件中的 Ipaddress。 (如果 xml 配置文件中的端点地址没有 localhost 地址)

2) 我将如何在 else 语句中编写代码以继续在目录中进行枚举?

        static void Main(string[] args)
    {
        var dir = Directory.EnumerateDirectories(@"C:\Program Files (x86)\Stuff\Noodles");
        foreach (var folder in dir)
        {
            var path = Directory.EnumerateFiles(folder, "*.config", SearchOption.AllDirectories);
            string newIPAddress = "10.246.31.4";
            foreach (var xmlfile in path)
            {
                var doc = XDocument.Load(xmlfile);
                var endpointsToUpdate = doc
                    .Descendants("endpoint")
                    .Where(x => new Uri((string)x.Attribute("address")).Host != "localhost")
                    .ToArray();

                // skip if there is nothing to update
                //if (!endpointsToUpdate.Any()) return;
                if (endpointsToUpdate.Any());
                {

                    foreach (var endpoint in endpointsToUpdate)
                    {
                        string address = (string)endpoint.Attribute("address");
                        string pattern = "//\\d[^:]+";
                        address = Regex.Replace(address, pattern, "//" + newIPAddress);

                        endpoint.Attribute("address").SetValue(address);
                    }
                    else 
                    {

                    }

                    doc.Save(xmlfile);
                } 
            }
        }
    }
}

}

【问题讨论】:

  • 我从以前的帖子中认出了我的代码。试试: XElement[] endpointsToUpdate = doc .Descendants("endpoint") .Where(x => (string)x.Descendants("dns").FirstOrDefault().Attribute("value") != "localhost") 。 ToArray();
  • 没有任何改变。当我在“if (!endpointsToUpdate.Any()) return;”之后单步执行它时它跳过了 foreach 语句,所以它几乎就像是因为第一个文件夹在它的配置文件中有 localhost。代码读取它,因为没有什么要更新的,所以它只是结束程序
  • 你所有的样本都有本地主机,所以它什么都不返回。将 localhost 更改为示例中的其他内容。
  • 我不是要更改 dns 值,dns 值应该始终是本地主机。我正在尝试将端点地址更新为 newIPAdress,如果它具有像“net.tcp://10.249.30.4:7732”这样的实际 IP 地址,但如果它具有 net.tcp://localhost:7732/ 那么它应该是单独留下。我想我可能给你造成了误解,我很抱歉
  • 我试图按照你上面黄色的代码,它正在测试!=“localhost”。所以我的代码给出了不包含本地主机的元素。

标签: c# .net xml loops foreach


【解决方案1】:

只需将模式的第一个字符更改为 \d(一个数字)即可解决问题:

           string newIP = "10.36.31.4";

            string addr1 = "net.tcp://localhost:7732/AuthenticationServices/Secure";
            string addr2 = "net.tcp://10.249.30.4:7732/EventSubscriberServices/Secure";

            string pattern = "//\\d[^:]+";

            string newaddr1 = Regex.Replace(addr1, pattern, "//" + newIP);
            string newaddr2 = Regex.Replace(addr2, pattern, "//" + newIP); 

【讨论】:

  • 我的文件仍未更新。我确定可能是路径没有被定位
  • 检查文件的日期以确定它们是否已保存。不需要 WHERE。正则表达式更改将取而代之。
  • 我就是这就是为什么我知道正在发生的事情是它只通过 @"C:\Program Files (x86)\Stuff\Noodles" 中的第一个文件夹,而不是其余的。此目录中有 10 个不同的文件夹,但它在第一个停止。
  • 现在我们知道发生了什么。在处理其中一个文件时遇到异常,一旦发生异常,您将退出 for 循环。在 for 循环中添加异常处理程序将允许代码继续并处理其余文件。然后,您应该返回并找出至少一个文件导致异常的原因。它可能具有不允许读取或写入文件的凭据。可能是另一个应用程序正在锁定文件。
  • 我对我的帖子进行了编辑,请检查一下,我想通了。我的 foreach 循环中间有一个“返回”。我把它注释掉了,并用一个肯定的 if 语句代替了它。所以它说如果有一个端点要更新,然后更新它,然后继续枚举,如果没有,那么继续枚举。我现在的问题是我将在 else 语句中放入什么来继续目录中的枚举?
【解决方案2】:

如果您使用正则表达式仅匹配不包含特定字符串(即本地主机)的字符串怎么办?因此,如果字符串不包含 localhost,请执行替换,否则跳过替换。反之亦然,无论您选择查看它。

^(?!.DontMatchThis).$

【讨论】:

    猜你喜欢
    • 2021-03-07
    • 2014-02-18
    • 2015-06-20
    • 2021-10-27
    • 2011-01-08
    • 2014-04-01
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    相关资源
    最近更新 更多