如何删除属性的Namespaceprefix?

时间:2014-08-08 07:14:24

标签: c# xml

在过去的几天里,我试图删除节点命名空间的前缀。 在一些帮助下我完成了它:

Xml(之前):

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1assembly.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="Executable.exe"/>
 <description asmv2:iconFile="Icon.ico" xmlns="urn:schemas-microsoft-com:asm.v1" />
  <dependency>
    <dependentAssembly dependencyType="preRequisite">
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly dependencyType="install">
    </dependentAssembly>
  </dependency>
    <file name="Populatedfile.dll.deploy" size="123">
    </file>

C#代码:

 var doc = XDocument.Load("Xmlfile");
 doc.Root.Attribute(XNamespace.Xmlns + "asmv2").Remove();
 XNamespace ns = "urn:schemas-microsoft-com:asm.v2";
 doc.Descendants(ns + "dependentAssembly")
     .Where(x => (string)x.Attribute("dependencyType") == "install")
     .Select(x => x.Parent)
     .Remove();
 doc.Descendants(ns + "file").Remove();
 doc.Save("XmlFile");

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: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="Executable.exe" />
<description p8:iconFile="Icon.ico" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:p8="urn:schemas-microsoft-com:asm.v2" />
<dependency>
 <dependentAssembly dependencyType="preRequisite">
 </dependentAssembly>
</dependency>

所以问题是:

正如我们在第二个Xml-File(之后的Xml)中看到的那样,将iconFile的前缀从asmv2:更改为p8并在同一个节点中更改<description> )它添加了一个名为p8的新命名空间,这个Namespce不允许我更新Xmlfile(使用Mage.exe) 所以解决方案是:<description iconFile="Icon.ico" xmlns="urn:schemas-microsoft-com:asm.v1" />

或:<description asmv2:iconFile="Icon.ico" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"/>

问题是:

如何进入<description>节点以删除/重命名(如果可能)p8命名空间?

我尝试使用:doc.Root.Attribute(XNamespace.Xmlns + "p8").Remove();但它抛出一个名为:System.NullReferenceException的异常

请帮帮我:)

一如既往,只要你有建设性,你就可以纠正我:)

更新/答案:

    var doc = XDocument.Load("Xmlfile");
    try
    {
        doc.Root.Attribute(XNamespace.Xmlns + "asmv2").Remove();
    }
    catch (NullReferenceException) {}
    XNamespace ns = "urn:schemas-microsoft-com:asm.v2";
    doc.Descendants(ns + "dependentAssembly")
       .Where(x => (string)x.Attribute("dependencyType") == "install")
       .Select(x => x.Parent)
       .Remove();
    doc.Descendants(ns + "file").Remove();
    doc.Save(filePath);
    foreach (var attr in doc.Descendants()
                            .SelectMany(d => d.Attributes())
                            .Where(a => a.Name.Namespace == ns))
     {
        attr.Parent.Add(new XAttribute(attr.Name.LocalName, attr.Value));
        attr.Remove();
     }
     doc.Save(filePath);
    }

1 个答案:

答案 0 :(得分:2)

如果我正确地阅读了您的要求,您需要以下内容:

foreach (var attr in doc.Descendants()
                        .SelectMany(d => d.Attributes())
                        .Where(a => a.Name.Namespace == ns))
{
   attr.Parent.Add(new XAttribute(attr.Name.LocalName, attr.Value));
   attr.Remove();
}