Poco c++ Library 之xml 的使用

19 篇文章 0 订阅

POCO XML 操作文档 

它操作xml 有两种方式, sax 和dom, 这时只介绍DOM , 注意 dom 元素有限制, 子节点下不同名的元素不能超过251个.

注: poco xml 只支持utf8 所以你的所有字符串都必须先转换成 utf8 才能使用.



读XML :


我们得先清楚几个问题:

1 我这里只介绍 DOMParser DOMWriter.
2 POCO 的思想 它把,Element,attribute 都看作是节点. 

如何打开一个文件?
方法1:直接传路径
DOMParser parser;
AutoPtr<Document> pDoc ;
pDoc = parser.parse("SC_PhoneInfo.xml");//这里可以传文件路径进去 把pDoc记住后面会用到
这里我们调用的是它个这个构造函数:
Document* DOMParser::parse(const XMLString& uri);


方法2:用标准库中的流(这个没测试,按理说应该可以,因为我测试过写的)

std::ifstream file;
file.open("text1.xml",)
pDoc = parser.parse(file);


遍历结点:
NodeIterator it(pDoc, NodeFilter::SHOW_ALL);
Node* pNode = it.nextNode();
while (pNode)
{
std::cout << pNode->nodeName() << ":" << pNode->nodeValue() << std::endl;  节点名称和节点值
pNode = it.nextNode();
}


方法2:

怎么获取节点的属性?
我们得先获取到这个节点Node获取到后Node中有一个成员函数attributes(),它返回一个NamedNodeMap指针对象(这个NamedNodeMap和NodeList的使用类似不过它多了几个方法).
如何根据已知的路径得到指定的节点
这里有个文档上没说清楚的地方,就是节点得从第二层开始
 Node* Document::getNodeByPath(const XMLString& path);

例:

- <Phone>
- <PhoneClass name="日韩品牌">
- <PhoneManufacture name="Samsung">

strPath = "/PhoneClass[@name='日韩品牌']/PhoneManufacture[@name='Samsung']"
strPath =  "/PhoneClass/PhoneManufacture[@name='Samsung']"
Node *pParent = m_pDoc->getNodeByPath(strPath);


注:Node中还有 childNodes 返回它所有的子结点(NodeList), 和nextSibling 返回它的下一个兄弟结点.


写xml

这个貌似不复杂简单介绍就可.

问题: 如何创建一个xml文件.
方法1: 
  AutoPtr<Poco::XML::Document> pDoc = new Poco::XML::Document;
  AutoPtr<Poco::XML::Element> myRoot = pDoc->createElement("Root");
  AutoPtr<Poco::XML::Element> myChild = pDoc->createElement("Child");
  AutoPtr<Poco::XML::Element> myGrandChild = pDoc->createElement("GrandChild");
  AutoPtr<Poco::XML::Text> nameNode = pDoc->createTextNode("my_name_is_xiaoqiang");
  AutoPtr<Poco::XML::ProcessingInstruction> pi = pDoc->createProcessingInstruction("xml","version='1.0' encoding='UTF-8'" );
  AutoPtr<Poco::XML::Comment> comm = pDoc->createComment("new_day");


  myGrandChild->appendChild(nameNode);
  myChild->appendChild(myGrandChild);
  myRoot->appendChild(myChild);
  pDoc->appendChild(pi);
  pDoc->appendChild(comm);

  pDoc->appendChild(myRoot);


Poco::XML::DOMWriter writer;
  writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT);
  writer.writeNode(std::cout,pDoc);


方法2: 用流.


增加结点:


AutoPtr<Document> pDoc = new Document;
AutoPtr<Element> pRoot = pDoc->createElement("Phone");
pDoc->appendChild(pRoot);
AutoPtr<Element> pChild1 = pDoc->createElement("CallLog");

pRoot->appendChild(pChild1);//子结点

//如果还想插入孙结点就

pChild1->appendChild(XXXX);



//孙结点上..
XXXX->appendChild(YYY);


很简单了就像树一样一层一层的住上插就可以了.



如果要添加设置几个属性节点怎么办? //测试代码会有内存泄漏. 要用智能指针.


Document* pDoc = new Document;
AutoPtr<Element> pRoot = pDoc->createElement("Phone");

Element* pChild = pDoc->createElement("Log");


方法1:

pChild ->setAttribute("flux",flux);


方法2:

Attr *pAttr  = pDoc->createAttribute("ss");  //属性节点名称 ss
pAttr->setNodeValue("111");//属性节点名称 ss 的值 111

pChild->setAttributeNode(pAttr); //添加到指定的结点上

Attr *pAttr1  = pDoc->createAttribute("ss3");//属性节点名称 ss

pAttr1->setNodeValue("11331");//属性节点名称 ss3的值 11331
pChild->setAttributeNode(pAttr1);//添加到指定的结点上

//插入到指定的结点上
pRoot->appendChild(pChild);
pDoc->appendChild(pRoot);

如果你想在查找到的结点上增加内容可以这样:

Poco::XML::Node* pNode =  pDoc->getNodeByPath(strPath); //查找到结点
Poco::AutoPtr<Poco::XML::Element> pElem = pDoc->createElement("site"); // 创建结点
pNode->appendChild(pElem); // 插入它 这个参数是Node 但是因为Element继承于它所以可以使用.


<item>111<item>  ///111 也算是item的子结点,但它的类型是#text.

并不是所的xml 类中的指针加AutoPtr 都行

像创建类的加上我目前没发现问题. 如是返回指针就不要加了.加了会出错.

Poco::XML::Node* pNode =  pDoc->getNodeByPath(strPath);  //正确
Poco::AutoPtr<Poco::XML::Node> pNode =  pDoc->getNodeByPath(strPath); //错误.
Poco::AutoPtr<Poco::XML::Element> pElemdate = pDoc->createElement("date"); // 正确
Poco::AutoPtr<Poco::XML::Text> pText = pDoc->createTextNode(strData); //正确
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值