XDocument and XmlDocument

从.NET 3.5开始,System.Xml.Linq.XDocument替代了System.Xml.XmlDocument对象,它更容易处理XML文档。

XDocument保存到字符串或文件中

因为StringBuilder使用UTF-16编码,所以保存到字符串中时,不能自定义字符编码。

XDocument xDocument = new XDocument();
xDocument.Add(this.PMOPUserControlModel.Recipe.GetLayoutXElement());

//both StringBuilder and String objects use UTF-16 encoding to store characters
StringBuilder sb = new StringBuilder();
XmlWriterSettings xws = new XmlWriterSettings();
xws.Indent = true;
using (XmlWriter xw = XmlWriter.Create(sb,xws))
{
    xDocument.WriteTo(xw);
}

string str = sb.ToString();

xDocument.Save(filePath);

XDocument & XElement

除非需要使用XDocument的函数,否则XDocument和XElement是等价的。

You only have to create XDocument objects if you require the specific functionality provided by the XDocument class. In many circumstances, you can work directly with XElement. Working directly with XElement is a simpler programming model.

XDocument derives from XContainer, so it can contain child nodes. However, XDocument objects can have only one child XElement node. This reflects the XML standard that there can be only one root element in an XML document.

转义字符

XML文档中不允许出现以下几个关键字,使用XmlSerializer序列化xml文本时,会自动把字符串中的关键字进行转义处理。

&lt; 	<	小于号
&gt;	>	大于号
&amp;	&	和
&apos;	'	单引号
&quot;	"	双引号

XPath

XDocument xDocument = XDocument.Load(UserConfigurationPath);

XElement xElementNode = xDocument.XPathSelectElement("configuration/appSettings/add[@key='PMHost']");
IpAddress = xElementNode.Attribute("value").Value;

xElementNode = xDocument.XPathSelectElement("configuration/appSettings/add[@key='PMPort']");
Port =int.Parse(xElementNode.Attribute("value").Value);

XPath & Namespace

XDocument xDocument = XDocument.Load(pathElogTextRegistryLocal);
var namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("abb", "urn:abb-robotics-registry-elog-text");
IEnumerable<XElement> xElementNodes = xDocument.XPathSelectElements("/elogtext_registry/abb:entry", namespaceManager);
foreach (XElement xElementNode in xElementNodes)
{
    string pathElogTextRemote = Path.Combine(xElementNode.Attribute("prepath").Value, language, xElementNode.Attribute("postpath").Value);
    string pathElogTextLocal = Path.Combine("Irc5Files", RobControllerInfo.SystemId, language, Path.GetFileName(pathElogTextRemote));
    stream = await robControllerConnection.FileTransfer.GetStream(pathElogTextRemote);
    using (FileStream DestinationStream = new FileStream(pathElogTextLocal, FileMode.Create))
    {
        await stream.CopyToAsync(DestinationStream);
    }
}