C++ XML, 轻松上手!






4.91/5 (62投票s)
C++ 的 XML DOM 包装器。
引言
本文是我上一篇文章《IXMLDDOMDocument 的包装类》的续篇。
之所以将它作为一篇独立文章发布而不是更新,是因为它与前一篇在任何方面都不兼容。有不同的类和函数。主要区别在于,此包装器直接使用 XML 指针,无需先解析 XML 树,从而带来了显著的速度提升。
用法
将文件 "XmlNodeWrapper.cpp" 添加到项目的源文件中。
在您希望使用包装器的文件中包含文件 "XmlNodeWrapper.h"。
#include "XmlNodeWrapper.h"
参考
CXmlDocumentWrapper
构造函数
CXmlDocumentWrapper()
创建一个新的 XML 文档实例。您需要通过
Load()
或LoadXml()
加载文档。CXmlDocumentWrapper(IXMLDOMDocumentPtr pDoc)
将包装器附加到现有文档指针。将接受
IXMLDOMDocumentPtr
、IXMLDOMDocument*
指针或IDispatch*
指针作为输入。
方法
BOOL IsValid()
如果包装器具有指向 XML 文档的有效指针,则返回
TRUE
。MSXML2::IXMLDOMDocument* Detach()
将包装器与 XML 指针分离并返回指针。如果您在构造函数中传递了外部指针,并且不想减少该指针的引用计数,则此方法很有用。
MSXML2::IXMLDOMDocument* Clone()
创建并返回文档的克隆。
建议用法
CXmlDocumentWrapper newDoc(sourceDoc.Clone());
BOOL Load(LPCTSTR path)
从磁盘文件加载文档。成功时返回
TRUE
。用法
CXmlDocumentWrapper doc; doc.Load("C:\\Test\\xmlSource.xml");
BOOL LoadXML(LPCTSTR xml)
从字符串加载文档。成功时返回
TRUE
。用法
CXmlDocumentWrapper doc; doc.LoadXML("<Root><SomeObject></SomeObject></Root>");
BOOL Save(LPCTSTR path = "")
将文档保存到磁盘文件。如果路径为空字符串或被省略,则使用当前文档的 URL。
MSXML2::IXMLDOMNode* AsNode()
将文档的根元素作为 XML 节点返回。
用法
CXmlNodeWrapper xmlNode(xmlDoc.AsNode());
CString GetXML()
以
CString
格式返回当前加载到文档中的 XML。CString GetUrl()
返回当前文档的 URL。注意:每次使用
Load()
或Save()
函数时,URL 都会更新。
CXmlNodeWrapper
构造函数
CXmlNodeWrapper()
创建一个空的节点包装器。您需要使用赋值运算符
=
或Attach()
来初始化此节点。CXmlNodeWrapper(MSXML2::IXMLDOMNodePtr pNode,BOOL bAutoRelease = TRUE)
从现有 XML 节点的 XML 指针创建包装器。将接受
IXMLDOMNodePtr
、IXMLDOMNode*
或IDispatch*
指针。如果bAutoRelease
参数为FALSE
,则在析构函数中将调用Detach()
。void operator=(MSXML2::IXMLDOMNodePtr pNode)
与上面相同。
方法
BOOL IsValid()
如果包装器中的 XML 指针有效,则返回
TRUE
。void SetValue(LPCTSTR valueName,LPCTSTR value)
void SetValue(LPCTSTR valueName,int value)
void SetValue(LPCTSTR valueName,short value)
void SetValue(LPCTSTR valueName,double value)
void SetValue(LPCTSTR valueName,float value)
void SetValue(LPCTSTR valueName,bool value)
为属性设置值。如果属性已存在,则更新其值;否则,将创建新属性。
CString GetValue(LPCTSTR valueName)
以
CString
格式返回属性的值。如果属性不存在,则返回空字符串。MSXML2::IXMLDOMNode* GetPrevSibling()
MSXML2::IXMLDOMNode* GetNextSibling()
获取此节点的下一个或上一个同级节点。如果不存在,则返回
NULL
。用法
CXmlNodeWrapper prevNode(theNode.GetPrevSibling()); CXmlNodeWrapper nextNode(theNode.GetNextSibling()); if (prevNode.IsValid()) { // Do things } else if (nextNode.IsValid()) { // Do things }
MSXML2::IXMLDOMNode* GetNode(LPCTSTR nodeName)
MSXML2::IXMLDOMNode* GetNode(int nodeIndex)
按索引或名称返回此节点的子节点。如果找不到节点,则返回
NULL
。按名称搜索时,仅返回第一个匹配的节点。用法
CXmlNodeWrapper childNode(theNode.GetNode(0)); if (!childNode.IsValid()) { childNode = theNode.GetNode("MyChild"); // Do things }
MSXML2::IXMLDOMNode* FindNode(LPCTSTR searchString)
通过评估 XSL 搜索模式返回单个节点(
selectSingleNode
函数的包装器)。用法
//Finds the node with the name "Object" // who's "Type" attribute equals "Simple": CXmlNodeWrapper resultNode( theNode.FindNode("//Object[@Type='Simple']"));
MSXML2::IXMLDOMNodeList* FindNodes(LPCTSTR searchStr)
通过评估 XSL 搜索模式返回节点列表(
selectNodes
函数的包装器)。用法
//Finds all the nodes with the name "Object" //who's "Type" attribute equals "Simple": CXmlNodeListWrapper nodeList( theNode.FindNodes("//Object[@Type='Simple']"));
long NumNodes()
返回子节点的数量。
MSXML2::IXMLDOMNode* Parent()
返回此节点的父节点,如果没有父节点则返回
NULL
。用法
CXmlNodeWrapper parentNode(theNode.Parent());
CString Name();
返回节点的名称。
CString GetText()
返回节点的文本内容。
void SetText(LPCTSTR text)
设置节点的文本内容。
MSXML2::IXMLDOMDocument* ParentDocument()
返回此节点所属的文档,如果不适用则返回
NULL
。用法
CXmlDocumentWrapper xmlDoc(theNode.ParentDocument());
MSXML2::IXMLDOMNode* Interface()
返回原始接口指针,用于调用包装器未提供的某些方法,或在不从包装器分离的情况下将接口传递给其他函数。
MSXML2::IXMLDOMNode* Detach()
在不调用
Release()
的情况下从 XML 指针分离并返回指针。CString GetXML()
以
CString
格式返回节点的 XML 内容。MSXML2::IXMLDOMNode* InsertNode(int index,LPCTSTR nodeName)
创建具有给定名称的新 XML 节点,并将其作为此节点的子节点插入。使用 index=0 作为第一个子节点插入,使用
index=NumNodes()
作为最后一个子节点插入。返回指向新节点的指针。用法
CXmlNodeWrapper newChild( theNode.InsertNode(theNode.NumNodes(),"MyNewChild"); newChild.SetValue("SomeValue","Undefined");
MSXML2::IXMLDOMNode* InsertNode(int index,MSXML2::IXMLDOMNodePtr pNode)
与上面相同。新子节点不是新创建的,而是接受指向现有节点的指针。
用法
// Create a copy of a document //and insert as a child into existing node CXmlDocumentWrapper doc; doc.Load("C:\\Temp\\xmlSource.xml); CXmlNodeWrapper sourceNode(doc.AsNode()); CXmlDocumentWrapper cloneDoc(doc.Clone()); sourceNode.InsertNode(0,cloneDoc.AsNode());
MSXML2::IXMLDOMNode* InsertAfter(MSXML2::IXMLDOMNode* refNode, LPCTSTR nodeName)
MSXML2::IXMLDOMNode* InsertBefore(MSXML2::IXMLDOMNode* refNode, LPCTSTR nodeName)
在引用节点之前或之后创建并插入具有给定名称的新子节点。返回新创建的节点。
MSXML2::IXMLDOMNode* InsertAfter(MSXML2::IXMLDOMNode *refNode, MSXML2::IXMLDOMNode *pNode)
在引用节点之后插入现有节点。返回插入的节点。
MSXML2::IXMLDOMNode* RemoveNode(MSXML2::IXMLDOMNodePtr pNode)
从此节点的子节点列表中移除指定的节点。返回指向已移除节点的指针。
void RemoveNodes(LPCTSTR searchStr)
通过评估 XSL 模式从此节点的子节点列表中移除节点。有关示例,请参见
FindNodes
。void ReplaceNode(MSXML2::IXMLDOMNode* pOldNode,MSXML2::IXMLDOMNode* pNewNode)
用新节点替换现有的子节点。
CXmlNodeListWrapper
构造函数
CXmlNodeListWrapper()
创建一个空的节点列表包装器,您必须使用赋值运算符
=
来初始化它。CXmlNodeListWrapper(MSXML2::IXMLDOMNodeListPtr pList)
从现有的
IXMLDOMNodeList
指针创建节点列表,将接受IXMLDOMNodeListPtr
、IXMLDOMNodeList*
指针或IDispatch*
指针。有关示例,请参阅CXmlNodeWrapper::FindNodes()
。void operator=(MSXML2::IXMLDOMNodeListPtr pList)
同上。
方法
BOOL IsValid()
如果列表指针有效,则返回
TRUE
。int Count()
返回列表中节点的数量。
MSXML2::IXMLDOMNode* Node(int index)
返回列表中的第 n 个节点。
用法
for (int i = 0; i < nodeList.Count(); i++) { CXmlNodeWrapper node(nodeList.Node(i)); // Do things }
void Start()
重置迭代器。有关示例,请参阅
Next()
。MSXML2::IXMLDOMNode* Next()
在迭代过程中返回列表中的下一个节点,如果没有则返回
NULL
。用法
nodeList.Start(); CXmlNodeWrapper node(nodeList.Next()); while (node.IsValid()) { // Do things node = nodeList.Next(); }
MSXML2::IXMLDOMDocument* AsDocument()
将节点列表转换为新文档,格式为:
<NodeList>THENODES</NodeList>
用法
CXmlDocumentWrapper doc(theList.AsDocument());
更新
示例现已可供下载。另外还包含了一些新函数:
int CXmlNodeWrapper::NumAttributes()
- 返回节点中的属性数量。CString CXmlNodeWrapper::NodeType()
- 返回节点的类型:"element"、"text" 等。CString CXmlNodeWrapper::GetAttribName(int index)
- 返回指定索引处的属性名称。CString CXmlNodeWrapper::GetAttribVal(int index)
- 返回指定索引处的属性值。