The xml and linqxml operations with namespaces are performed in the Linq to xml format.
Yesterday, we needed to operate on the csproj file using code to implement switching between different vs versions.
After XElement is used to read the csproj file, the desired object cannot be obtained.
The content of the csproj file is as follows:
<?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>bin\Debug\</OutputPath> <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup></Project>
I only intercepted some csproj files to illustrate the problem.
My initial code is:
XDocument doc = XDocument.Load(@"D:\Demo\AsyncDemo\AsyncDemo\AsyncDemo.csproj");XElement x = doc.Element("Project");
This x is always empty, and the following doc object is analyzed.
I found xuanjicang. This name is not a simple "project", but also has a namespace.
So how to obtain the node name with Namespace?
Okay. Let's look back at the XElement constructor:
Public XElement (XName name );
Note: The parameter type is XName, not string. Why can I use string? XName defines an implicit conversion. You can implicitly convert string to XName.
Therefore, for Namespace, you should also start with XNamespace, and then find a method that can be changed to XName. You can see the definition of XNamespace:
Public static XName operator + (XNamespace ns, string localName );
Adding the local name (string) to XNamespace is an XName, which is very simple.
Let's take a look at how to create an XNamespace:
Public static implicit operator XNamespace (string namespaceName );
It is also an implicit conversion... To see how to create a project with namespace:
static void TestXml() { XDocument doc = XDocument.Load(@"D:\Demo\AsyncDemo\AsyncDemo\AsyncDemo.csproj"); XNamespace v = "http://schemas.microsoft.com/developer/msbuild/2003"; XElement x = doc.Element(v + "Project"); }
Define a namespace and use it with a + string. In this way, we can get the desired object. The specific operation code is as follows:
static void TestXml() { string path = @"D:\Demo\AsyncDemo\AsyncDemo\AsyncDemo.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); }
All nodes to be operated must use the namespace and node name.
Hope to help you ......