我尝试使用SelectSingleNode
修改XML文件。
文件的结构是
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<BorlandProject>
<Delphi.Personality>
<Parameters>
...
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">True</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">4</VersionInfo>
<VersionInfo Name="MinorVer">1</VersionInfo>
<VersionInfo Name="Release">3</VersionInfo>
<VersionInfo Name="Build">559</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
...
...
...
我在VS C#上的代码是
using System.Xml;
namespace xmledit
{
class Program
{
private static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.Load("arm.xml");
var node = doc.SelectSingleNode("//VersionInfo[@Name='Build']");
if (node != null)
node.InnerText = "123";
doc.Save("temp.xml");
}
}
}
因此,我尝试使用VersionInfo
修改标记Name="Build"
,但SelectSingleNode
返回NULL
。
我做错了什么?
答案 0 :(得分:3)
您的xml文档有一个默认的命名空间xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
因此(我假设)您需要使用XmlNamespaceManager。
答案 1 :(得分:1)
此函数将为您的文档添加命名空间管理器。替换&#34; mysite&#34;无论你想要什么。在此之后,您可以使用&#34; mysite:[nodename]&#34;。
选择节点public static XmlNamespaceManager AttachNamespaces(ref XmlDocument xmldoc)
{
XmlNamespaceManager NS = default(XmlNamespaceManager);
XmlNode rootnode = default(XmlNode);
string strTest = null;
string attrname = null;
string ns = null;
NS = new XmlNamespaceManager(xmldoc.NameTable);
rootnode = xmldoc.DocumentElement;
strTest = GetAttribute(ref rootnode, "xmlns");
if (string.IsNullOrEmpty(strTest))
{
NS.AddNamespace("mysite", "http://www.mysite.com/");
}
else
{
NS.AddNamespace("mysite", strTest);
}
// Add namespaces from XML root tag
foreach (XmlAttribute attr in rootnode.Attributes)
{
attrname = attr.Name;
if (attrname.IndexOf("xmlns:") == 0 && !string.IsNullOrEmpty(attrname))
{
ns = attrname.Substring(7);
NS.AddNamespace(ns, attr.Value);
}
}
return NS;
}
辅助功能:
public static string GetAttribute(ref XmlNode mynode, string AttributeName, string DefaultValue = "")
{
XmlAttribute myattr = default(XmlAttribute);
string rtn = "";
if (mynode != null)
{
myattr = mynode.Attributes[AttributeName];
if (myattr != null)
{
rtn = mynode.Attributes[AttributeName].Value;
}
}
if (string.IsNullOrEmpty(rtn))
rtn = DefaultValue;
return rtn;
}
例如:
XmlDocument xmldoc = new XmlDocument;
// Load something into xmldoc
XmlNamespaceManager NS = AttachNamespaces(ref XmlDocument xmldoc);
XMLNode mynode = xmldoc.SelectSingleNode("//mysite:VersionInfo[@Name='Build']", NS);
答案 2 :(得分:0)
您需要定义命名空间:
看一下这个答案:SelectSingleNode returning null for known good xml node path using XPath
答案 3 :(得分:0)
@PålThingbø
您在Substring中使用了错误的位置,并且您的解决方案无法处理默认命名空间。
我修改了它,所以它现在适用于我。谢谢! (虽然仍然没有处理没有命名空间的“xmlns:”标记(attrname == 6)。我认为这会引发错误,因为XML中不允许这样做。
private static XmlNamespaceManager AttachNamespaces(XmlDocument xmldoc)
{
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmldoc.NameTable);
XmlNode rootnode = xmldoc.DocumentElement;
string strTest = GetAttribute(ref rootnode, "xmlns");
nsMgr.AddNamespace("mysite", string.IsNullOrEmpty(strTest) ? "http://example.com/" : strTest);
// Add namespaces from XML root tag
if (rootnode.Attributes != null)
foreach (XmlAttribute attr in rootnode.Attributes)
{
string attrname = attr.Name;
if (attrname.IndexOf("xmlns", StringComparison.Ordinal) == 0 && !string.IsNullOrEmpty(attrname))
{
if (attrname.Length == 5) // default Namespace
{
string ns = "default";
nsMgr.AddNamespace(ns, attr.Value);
}
else if (attrname.Length > 6)
{
string ns = attrname.Substring(6);
nsMgr.AddNamespace(ns, attr.Value);
}
}
}
return nsMgr;
}