。去掉();不删除和.Save();确实设置了每个节点的asmv

时间:2014-08-05 11:27:27

标签: c# xml

正如我在标题中所说:

.Remove();不会删除

.Save();确实在每个节点的前面设置asmv2

代码:

private void DeleteXmlPopulates()
    {
        string filePath = "C:\\Example\\Example.exe.manifest"
        var xml = XElement.Load(filePath);
        xml.Descendants().Where(x => x.Name == "dependentAssembly" && (string)x.Attribute("dependencyType") == "install").Remove();
        xml.Save(filePath);
    }

XML:

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
<asmv1:assemblyIdentity name="Example.exe" version="6.1.0.0" publicKeyToken="7f785aa0b92a51a3" language="neutral" processorArchitecture="x86" type="win32" />
<description asmv2:iconFile="Example.ico" xmlns="urn:schemas-microsoft-com:asm.v1" />
<application />
<entryPoint>
<assemblyIdentity name="Example" version="6.1.0.14132" language="neutral" processorArchitecture="x86" />
<commandLine file="Example.exe" parameters="" />
</entryPoint>
<trustInfo>
<security>
<applicationRequestMinimum>
<PermissionSet Unrestricted="true" ID="Custom" SameSite="site" />
<defaultAssemblyRequest permissionSetReference="Custom" />
</applicationRequestMinimum>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">    
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
  </requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentOS>
  <osVersionInfo>
    <os majorVersion="5" minorVersion="1" buildNumber="2600" servicePackMajor="0" />
  </osVersionInfo>
</dependentOS>
</dependency>
<dependency>
<dependentAssembly dependencyType="preRequisite">
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly dependencyType="install">
</dependentAssembly>
</dependency>

Xml文件中有一条评论:UAC Manifest Options If you want to change the Windows User Account Control level replace the requestedExecutionLevel node with one of the following. <requestedExecutionLevel level="asInvoker" uiAccess="false" /> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> If you want to utilize File and Registry Virtualization for backward compatibility then delete the requestedExecutionLevel node.

代码如何:(只是依赖部分,其余部分应相同)

<dependency>
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
</dependentAssembly>
</dependency>

代码的外观如下:(只是依赖部分,剩下的部分在每个节点前面都有asmv2)

<asmv2:dependency>
<asmv2:dependentAssembly dependencyType="preRequisite">
</asmv2:dependentAssembly>
</asmv2:dependency>

<asmv2:dependency>
<asmv2:dependentAssembly dependencyType="install" >
</asmv2:dependency>
</asmv2:dependentAssembly>

好的,更重要的问题(我们将尝试回答的问题)是.Save();为什么在每个节点前面设置asmv2:? 如果使用方法.Save();这是正常的,那么我会感到惊讶,因为MageUI.exe

不能再使用文件进行操作

我如何解决这个问题或避免它?

我希望有建设性的批评:)

2 个答案:

答案 0 :(得分:1)

似乎是一个典型的例子 -

Mixed Declarative Code/Imperative Code Bugs (LINQ to XML)

您正在删除项目,同时对其执行查询,但Save正常工作,因为它没有任何此类问题。

xml.Descendants().Where(x => x.Name == "dependentAssembly" && (string)x.Attribute("dependencyType") == "install").Remove();

您应该尝试使用单独的列表删除它们。正如MSDN中提到的那样 -

http://msdn.microsoft.com/en-us/library/system.xml.linq.xnode.remove(v=vs.110).aspx

  

在LINQ to XML编程中,您不应该操纵或修改集合   查询该集合中的节点时的节点数。实际上   这意味着你不应该迭代一组节点和   删除它们。相反,您应该将它们实现为List by   使用ToList扩展方法。然后,你可以迭代   删除节点的列表。有关更多信息,请参阅混合   声明性代码/命令式代码错误(LINQ to XML)。

     

或者,如果   如果要删除一组节点,建议您使用   扩展名。移除方法。此方法将节点复制到列表,和   然后迭代列表以删除节点。

理想的解决方案与此类似 -

var itemsToRemove = xml.Descendants().Where(x => x.Name == "dependentAssembly" && (string)x.Attribute("dependencyType") == "install").ToList();
itemsToRemove.Remove();

示例 - http://msdn.microsoft.com/en-us/library/bb357554(v=vs.110).aspx

答案 1 :(得分:0)

您的XML具有默认命名空间(xmlns="urn:schemas-microsoft-com:asm.v2")。您需要使用&#34; XNamespace +元素名称&#34;引用命名空间中的元素:

XNamespace ns = "urn:schemas-microsoft-com:asm.v2";
xml.Descendants()
   .Where(x => x.Name == ns+"dependentAssembly" && (string)x.Attribute("dependencyType") == "install")
   .Remove();

或者只使用XElement.Name.LocalName

忽略命名空间
xml.Descendants()
   .Where(x => x.Name.LocalName == "dependentAssembly" && (string)x.Attribute("dependencyType") == "install")
   .Remove();