【问题标题】:Merge old and new XML file using C#使用 C# 合并新旧 XML 文件
【发布时间】:2014-03-09 01:52:00
【问题描述】:

在过去的几周里,我一直在尝试创建一个 C# 应用程序,它将 2 个 XML 文件合并到一个新的 XML 文件中。就其本身而言,当您知道 XML 文件的布局时,这并不难做到,但在这种情况下,我不知道文件的布局。它需要是 100% 动态的,无需在代码中命名标签。

应用程序需要通过以下方式将 2 个文件合并在一起。旧文件中的标签处于领先地位,这些标签的值需要在最终结果中,但其中不能有任何重复。但是如果新的 XML 文件中有新的标签,则需要将其添加到最终的 XML 文件中的正确位置。

为了向您展示我的意思,我创建了以下示例:

XML 文件 1:

    <?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="BaseAddress" value="http://HOSTNAME:8820/" />
    <add key="OIPServerUrl" value="http://HOSTNAME:4512/" />
    <add key="WFAddress" value="http://HOSTNAME:8804" />
    <add key="WFUser" value="USER" />
    <add key="WFPassword" value="" />
    <add key="SiteRoot" value="somepath" />
    <add key="AlternateImages" value="somepath" />
    <add key="DataFolder" value="somepath2222" />
    <add key="ClientSettingsProvider.ServiceUri" value="" />
  </appSettings>
  <!-- Non User configurable part -->
  <system.serviceModel>
    <services>
      <service name="S4M.Gen.Services.OIPData">
        <endpoint binding="webHttpBinding" contract="S4M.Gen.Model.IOIPData" behaviorConfiguration="WebHttpJsonBehavior">
        </endpoint>
      </service>
      <service name="S4M.OIP.Factory.Services.CSDMService">
        <endpoint binding="webHttpBinding" contract="Base.Model.ServiceContracts.IDMService" behaviorConfiguration="WebHttpJsonBehavior">
        </endpoint>
      </service>
      <service name="S4M.WebServerService.StaticFileService">
        <endpoint binding="webHttpBinding" behaviorConfiguration="web" contract="S4M.WebServerService.IStaticFileService">
        </endpoint>
      </service>
    </services>
    <bindings>
      <webHttpBinding>
        <binding contentTypeMapper="Base.Service.ServiceContracts.RawMapper, Base.Service" />
      </webHttpBinding>
    </bindings>
    <extensions>
      <behaviorExtensions>
        <add name="webHttpJson" type="Base.Service.ServiceContracts.WebHttpJsonElement, Base.Service" />
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp />
        </behavior>
        <behavior name="WebHttpJsonBehavior">
          <webHttpJson />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
  </startup>
  <system.web>
    <membership defaultProvider="ClientAuthenticationMembershipProvider">
      <providers>
        <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
      </providers>
    </membership>
    <roleManager defaultProvider="ClientRoleProvider" enabled="true">
      <providers>
        <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
      </providers>
    </roleManager>
  </system.web>
</configuration>

XML 文件 2:

    <?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="BaseAddress" value="http://HOSTNAME:8820/" />
    <add key="OIPServerUrl" value="http://HOSTNAME:4512/" />
    <add key="WFAddress" value="http://HOSTNAME:8804" />
    <add key="WFUser" value="USER" />
    <add key="WFPassword" value="" />
    <add key="SiteRoot" value="somepath" />
    <add key="AlternateImages" value="somepath" />
    <add key="DataFolder" value="somepath" />
    <add key="ClientSettingsProvider.ServiceUri" value="" />
    <add key="RedirectCode" value="TemporaryRedirect"/> <!-- NEW tag -->
  </appSettings>
  <!-- Non User configurable part -->
  <system.serviceModel>
    <services>
      <service name="S4M.Gen.Services.OIPData">
        <endpoint binding="webHttpBinding" contract="S4M.Gen.Model.IOIPData" behaviorConfiguration="WebHttpJsonBehavior">
        </endpoint>
      </service>
      <service name="S4M.OIP.Factory.Services.CSDMService">
        <endpoint binding="webHttpBinding" contract="Base.Model.ServiceContracts.IDMService" behaviorConfiguration="WebHttpJsonBehavior">
        </endpoint>
      </service>
      <service name="S4M.WebServerService.StaticFileService">
        <endpoint binding="webHttpBinding" behaviorConfiguration="web" contract="S4M.WebServerService.IStaticFileService">
        </endpoint>
      </service>
    </services>
    <bindings>
      <webHttpBinding>
        <binding contentTypeMapper="Base.Service.ServiceContracts.RawMapper, Base.Service" />
      </webHttpBinding>
    </bindings>
    <extensions>
      <behaviorExtensions>
        <add name="webHttpJson" type="Base.Service.ServiceContracts.WebHttpJsonElement, Base.Service" />
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp />
        </behavior>
        <behavior name="WebHttpJsonBehavior">
          <webHttpJson />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
  </startup>
  <system.web>
    <membership defaultProvider="ClientAuthenticationMembershipProvider">
      <providers>
        <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
      </providers>
    </membership>
    <roleManager defaultProvider="ClientRoleProvider" enabled="true">
      <providers>
        <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
      </providers>
    </roleManager>
  </system.web>
</configuration>

最终结果:

    <?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="BaseAddress" value="http://HOSTNAME:8820/" />
    <add key="OIPServerUrl" value="http://HOSTNAME:4512/" />
    <add key="WFAddress" value="http://HOSTNAME:8804" />
    <add key="WFUser" value="USER" />
    <add key="WFPassword" value="" />
    <add key="SiteRoot" value="somepath" />
    <add key="AlternateImages" value="somepath" />
    <add key="DataFolder" value="somepath2222" />
    <add key="ClientSettingsProvider.ServiceUri" value="" />
    <add key="RedirectCode" value="TemporaryRedirect"/> <!-- NEW tag -->
  </appSettings>
  <!-- Non User configurable part -->
  <system.serviceModel>
    <services>
      <service name="S4M.Gen.Services.OIPData">
        <endpoint binding="webHttpBinding" contract="S4M.Gen.Model.IOIPData" behaviorConfiguration="WebHttpJsonBehavior">
        </endpoint>
      </service>
      <service name="S4M.OIP.Factory.Services.CSDMService">
        <endpoint binding="webHttpBinding" contract="Base.Model.ServiceContracts.IDMService" behaviorConfiguration="WebHttpJsonBehavior">
        </endpoint>
      </service>
      <service name="S4M.WebServerService.StaticFileService">
        <endpoint binding="webHttpBinding" behaviorConfiguration="web" contract="S4M.WebServerService.IStaticFileService">
        </endpoint>
      </service>
    </services>
    <bindings>
      <webHttpBinding>
        <binding contentTypeMapper="Base.Service.ServiceContracts.RawMapper, Base.Service" />
      </webHttpBinding>
    </bindings>
    <extensions>
      <behaviorExtensions>
        <add name="webHttpJson" type="Base.Service.ServiceContracts.WebHttpJsonElement, Base.Service" />
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp />
        </behavior>
        <behavior name="WebHttpJsonBehavior">
          <webHttpJson />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
  </startup>
  <system.web>
    <membership defaultProvider="ClientAuthenticationMembershipProvider">
      <providers>
        <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
      </providers>
    </membership>
    <roleManager defaultProvider="ClientRoleProvider" enabled="true">
      <providers>
        <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
      </providers>
    </roleManager>
  </system.web>
</configuration>

我目前的代码如下:

 XDocument doc1 = XDocument.Load(@"C:\Users\Jack\Desktop\1.config");
 XDocument doc2 = XDocument.Load(@"C:\Users\Jack\Desktop\2.config");

 XDocument newdoc = new XDocument();


 var query1 = from el
       in doc2.Elements().Except(doc1.Elements())
       select el;
 var query2 = from el
       in doc1.Elements().Except(doc2.Elements())
       select el;

       var query = query2.Except(query1);

 foreach (var item in query)
 {
      newdoc.Add(item);

      Console.WriteLine(item);
 }
 newdoc.Save(@"C:\Users\Jack\Desktop\new.config");
 Console.ReadLine();

我已经为此工作了很长时间,但我似乎无法弄清楚。有人可以帮我吗?

【问题讨论】:

  • 完全不同的xmls。并且很难从最终的 xml 中读取,你想合并什么?应用设置?服务?行为?反正算了。如果您在开始时发布了正确的 xml,我不会回答这个问题。
  • 在查看原始示例 xml 之后假设 xmls 输入只有一级深度(根 > 元素,而不是根 > 元素 > 子元素 > ...)。我的回答不适用于最近的 xml。

标签: c# xml merge


【解决方案1】:

你可以试试这个方法:

XDocument doc1 = XDocument.Load(@"C:\Users\Jack\Desktop\1.config");
XDocument doc2 = XDocument.Load(@"C:\Users\Jack\Desktop\2.config");
var query1 =
            doc2.Root.Elements().Where(
                o => !doc1.Root.Elements().Select(p => p.Name.LocalName).Contains(o.Name.LocalName));
foreach (var item in query1)
{
    doc1.Root.Add(item);
}
doc1.Save(@"C:\Users\Jack\Desktop\new.config");

【讨论】:

  • 我已经尝试了该解决方案,但它没有从 doc2 添加任何新标签。但是来自 doc1 的数据被正确添加了
  • 我用您发布的示例输入进行了尝试,输出与您的 Final Result 相同,但元素顺序不同。尝试检查您的文件(1.config 和 2.config)的内容?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 2018-06-22
  • 2017-12-10
  • 2016-09-02
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
相关资源
最近更新 更多