1. 程式人生 > 其它 >Linq to xml 操作帶名稱空間的xml

Linq to xml 操作帶名稱空間的xml

 昨天需要操作用程式碼操作csproj檔案,實現不同vs版本的切換。

在用XElement讀取了csproj檔案以後怎麼也獲取不到想要的物件。

反反覆覆試驗了好多次都不得要領:先看下csproj檔案的內容:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)$(MSBuildToolsVersion)Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)$(MSBuildToolsVersion)Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{EC9D3364-405E-4931-8148-779183C72A40}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>AsyncDemo</RootNamespace>
    <AssemblyName>AsyncDemo</AssemblyName>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>binDebug</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>

</Project>

因為只是為了說明問題,我只截取了一部分csproj檔案

我最初的程式碼是:

XDocument doc = XDocument.Load(@"D:DemoAsyncDemoAsyncDemoAsyncDemo.csproj");
XElement x = doc.Element("Project");

這個x始終為空,最後分析了下doc物件

果然找到了玄機,這個name並不是一個單純“project”,還帶有名稱空間。

那麼如何獲得這個帶有Namespace的節點名哪?

好吧,讓我們回過頭來看看XElement的建構函式:

public XElement(XName name); 注意哦,引數的型別是XName,而不是string,那麼平時為什麼能用string哪?XName定義了一個隱式的轉換,可以把string隱式的轉換成XName。

所以,關於Namespace自然也要從XNamespace入手,然後找一個能夠變成XName的方法,察看XNamespace的定義,就可以看到:

public static XName operator +(XNamespace ns, string localName); 只要把XNamespace加上本地名稱(string),就是一個XName了,非常簡單。

再看看如何建立一個XNamespace:

public static implicit operator XNamespace(string namespaceName); 又是隱式轉換。。。來看看具體如何建立一個帶namespace的project吧:

 static void TestXml()
        {
            XDocument doc = XDocument.Load(@"D:DemoAsyncDemoAsyncDemoAsyncDemo.csproj");
            XNamespace v = "http://schemas.microsoft.com/developer/msbuild/2003";
            XElement x = doc.Element(v + "Project");
        }

 定義一個namespace,在使用時直接+string即可。這樣就可以得到我們想要的物件了,具體操作程式碼如下:

 static void TestXml()
        {
            string path = @"D:DemoAsyncDemoAsyncDemoAsyncDemo.csproj";
            XDocument doc = XDocument.Load(path);
            XNamespace v = "http://schemas.microsoft.com/developer/msbuild/2003";
            var x = doc.Element(v + "Project").Elements(v+"PropertyGroup");
            foreach (var e in x)
            {
                XElement element = e.Element(v + "AssemblyName");
                if(element!=null)
                {
                    element.SetValue("abcd");
                }
            }
            doc.Save(path);
        }

這裡面所有需要操作的節點都要採用名稱空間加節點名的方式。

希望對您有所幫助……