Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Monday, May 26, 2008

How to create a new XmlElement

XmlNode是一个Context相关的对象, 你不能直接调用XmlNode的构造子来创建一个XmlNode. 要创建一个XmlNode有两个方法. 假设要在xmlParentNode下创建一个newNode.
方法1: 通过XmlDocument的CreateElement方法创建一个XmlNode
  public XmlElement CreateElement(prefix,localName,namespaceURI),如果元素带有namespace,必须加上namespaceURI, 比如:
步骤1:XmlElement newNode= docNode.CreateElement("w", "br", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
步骤2:xmlParentNode.InsertAfter(br, rNode.FirstChild);

方法2: 不是直接创建XmlElement,而是通过修改xmlParentNode的InnerXml文本, 来增加一个节点.记住:如果新加的内容包含前缀,一定要加上namespace URI.否则会报错的.  

xmlParentNode.InnerXml= @"<w:r xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main""><w:rPr>
</w:rPr>
<w:br/>
<w:t>Some string </w:t></w:r>"
;

Monday, May 5, 2008

How to handle xml namespace and xpath by using Linq Xml


.Net3.5对XML的支持更进一步, 你可以彻底地抛弃Dom处理方式了. 因为XDocument和XElement以及XNode比之前的XmlDocument和XmlNode处理速度更快.



下面是一个相对较为复杂的例子, 其中展现了怎样处理Xml的Namespace以及如何使用XPath来定位一个Xml元素.



/// <summary>
/// 查找所有节点名为p:cNvPr的Xml元素
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_SelectElementByXPath_Click(object sender, EventArgs e)
{
XDocument xDoc=XDocument.Load(@"c:\\slide1.xml");


//using System.Xml.XPath
// XElement或XDocument之所以有能力处理XPath, 是靠System.Xml.XPath.Extensions这个扩展static类提供的功能
// public static IEnumerable<XElement> XPathSelectElements(this XNode node, string expression, IXmlNamespaceResolver resolver)
// XPathSelectElements()函数还需要一个参数作为XML Namespace的解析器, 而XmlNamespaceManager类就是一个这样的解析器,
// 所以还需要引入System.Xml命名空间, 来创建一个XmlNamespaceManager对象

NameTable nt = new NameTable();
XmlNamespaceManager nameMgr = new XmlNamespaceManager(nt);
nameMgr.AddNamespace("p", "http://schemas.openxmlformats.org/presentationml/2006/main");

//***注意参数应该是p:cNvPr, 而不是cNvPr
var elements = from element in xDoc.XPathSelectElements("//p:cNvPr",nameMgr)
select element ;
foreach (var element in elements)
{
System.Console.Out.Write(element);
System.Console.Out.WriteLine("==============");
}

}


/// <summary>
/// 查找所有节点名为p:cNvPr的Xml元素
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_SelectElementByDescendant_Click(object sender, EventArgs e)
{
XDocument xDoc = XDocument.Load(@"c:\\slide1.xml");
XNamespace xns = XNamespace.Get("http://schemas.openxmlformats.org/presentationml/2006/main");

//public IEnumerable<XElement> Descendants(XName name)

//***注意参数应该是cNvPr, 而不是p:cNvPr
var elements1 = from element in xDoc.Descendants(xns.GetName("cNvPr"))
select element ;

//因为XNamespace类重载了加法运算符号,
// 所以对一个XNamespace对象和一个localName字符串相加, 返回的是一个XName对象,
// 正是 XElement或XDocument的Descendants()函数所需要的参数类型

//下面代码返回的elements1, 和elements1是完全一样的
var elements2 = from element in xDoc.Descendants(xns + "cNvPr")
select element ;

foreach(var element in elements2)
{
System.Console.Out.Write(element) ;
System.Console.Out.WriteLine("==============");
}
}

Tuesday, March 11, 2008

Thursday, March 6, 2008

misunderstand when using XmlNode.SelectSingleNode function

Keywords: System.Xml, XmlNode, XPath


在使用System.Xml命名空间的XmlNode类, 有一个方法 XmlNode.SelectSingleNode(string xpath).


刚开始使用它时, 对它的作用理解有误. 如果XPath以"/"开始, 其意义为从根节点开始搜索Node. 原本想使用XmlNode456对象的SelectSingleNode(XPath123)方法, XPath123这个表达式所指的根节点应是XmlNode456, 但事实是, 这个函数仍以XmlNode456所在文档的根节点root作为搜索的起点.


要搜索Node456下的Child节点, 有2个方法, 最好使用方法2, 因为它更加简单.


方法1: 如果想通过SelectSingleNode()来搜索的话, 构建一个从根节点root指向Child的绝对路径的XPath, (XPath表达式应该以"./"开头)


方法2: 将Node456.OutXml赋值给一个tempXmlDocument., 然后再使用tempXmlDocument.SelectSingleNode(AbsoluteXPath), 可以定位到子节点. 这时候, 你可以用tempXmlDocument来直接提取Node456节点的内容, 如果还要修改Node456, 应该在修改tempXmlDocument之后, 再将修改后的内容保存到原有的Node456节点上.




XmlDocument tempXmlDocument = new XmlDocument();
//Load the xml from Node456
tempXmlDocument.LoadXml(Node456.OutXml);

//extract Info from tempXmlDocument
//...


//change the tempXmlDocument info
//...

//save the result after changed into the Node456
Node456.InnerXml = tempXmlDocument.DocumentElement.InnerXml;

Sunday, February 3, 2008

how to read binary file and save it into xml

Keywords: CDATA node of xml, FileStream, MemoryStream, Base64String


In xml document, you can define CDATA node to store some large text string. There is a constraint in xml document, the xml document only can contain text string.


How to save image data or other binary data into xml?


We can convert the binary data into Base64String data, then we can store the Base64String data into xml document. We can use the following approach to achive.


Approach1: BinaryFile===>Byte[]===>Base64String===>CDATA


The following is pseudo code:



byte[] buffer=File.ReadAllBytes(string path);


string base64String= Convert.ToBase64String();


XmlCDATA=new XmlCDATA(base64String);


XmlDocument.AddChild(XmlCDATA);



How to restore the Base64String data into a FileStream?


It is easy to reach. The procedure is just reverse the above process.

Friday, January 25, 2008

how to use XmlDocument.Save and XmlWriter

Keywords: XmlDocument class, XmlWriter, FileStream, StringBuilder


原本想使用XmlWriter来格式化一个文件流, 结果是: Xml是被格式化了, 但格式化后的字符串是append到原来的流中, 而不是重写到文件流中. 为什么会出现这个现象呢? 我们先分析一下原来的代码:




public void BeautifyXml(FileStream fileStream)
{
XmlDocument xmlDoc = new XmlDocument();

//1. 重置m_fileStream的position为0, 否则xmlDoc.Load可能会出现异常
fileStream.Position = 0;

//2. 加载m_FileStream的内容到xmlDoc
xmlDoc.Load(fileStream);

//3. 创建一个XmlWriterSettings对象, 设置它的Format
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.IndentChars = " ";

//4.创建一个输出到fileStream的XmlWriter
XmlWriter writer = XmlWriter.Create(fileStream, xmlWriterSettings);

//5.保存XmlDocument的内容, 即输出到fileStream
xmlDoc.Save(writer);
}

在step2之后,XmlDoc对象已经完成Xml的加载, 然后在step4创建了一个输出到fileStream的XmlWriter, step5用xmlDoc.Save(writer)输出Xml到流中. 可以想象保存动作执行顺序应该是xmlDoc.Save()--->writer--->fileStream, 在保存时fileStream还保存着原来未被格式化的内容, 所以writer将xml的内容追加到fileStream. 知道问题的原因, 解决方案就简单了. 在step5之前先将fileStream的内容清空,可以用下面语句


fileStream.SetLength(0);

Tuesday, January 22, 2008

handle XmlException raised when XmlDocument.Load(stream)

Keywords: System.XML.XmlDocument class, FileStream




当用一个XmlDocument对象的Load(stream)方法, 去加载一个xml文件时, 有时候会抛出"Root element is missing"这样的XmlException, 很多情况下并不是因为这个Xml文件真的缺少根节点, 或者这个xml不是well formed.


修改的方法是:将FileStream的Position属性设置为0.


if (fileStream.Length>0)


{fileStream.Position=0; //this code is necessary


xmlDocument.Load(fileStream) ;


}

Thursday, January 10, 2008

XPath Syntax on w3school


Keywords: Xml, XPath, Syntax


The following page is the authoritative reference.


http://www.w3schools.com/xpath/xpath_syntax.asp


Tuesday, January 8, 2008

How to build XPath expression


Keywords: XPath expression, xml tools


There is a software, Exchanger XML can help you to build XPath expression. It has Lite edition with free charge.


It is developed in Java. The production homepage is http://www.exchangerxml.com/