Top
首页 > 老文章 > 正文

[.net] 在传统com程序中使用xml

xml是.net的核心,现在我就向大家介绍阅读和编写xml程序以及如何使用微软的MSXML4的com组件转化xml语言。  
发布时间:2002-09-18 09:52        来源:        作者:李阳编译
xml是.net的核心。在所有有关.net的文章、白皮书或是帮助中总会有这三个字母。但在.net出现之前,xml已经深深的改变了一切,在“传统的”win32程序中你也可以发现它。这里,我将会介绍阅读和编写xml程序以及如何使用微软的MSXML4的com组件转化xml语言。 如果你没有安装MSXML4,你能够从以下链接获取:http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/001/766/msdncompositedoc.xml。遵循说明将它装到你开发要用的所有机器上。如果你计划分发你的MSXML4程序,你还需要获得分发用的cab文件。 如果你还不了解xml是什么,下面是一个xml的特点列表。xml是用以表示结构化和半结构化数据的符号: 1.是能读懂的简单明了的ASCII文本。 2.是易创建的ASCII文本; 3.在任何的语言和操作系统中,利用免费和可获得(通常是免费)的组件,行数不多的代码就可处理; 4.利用同样的组件,只需几行代码就可创建; 5.易被转化成html,pdf,ppt以及很多其它打印友好和显示友好的格式; 6.能够利用很多可获取的组件在几乎所有的数据库中来回移植和维护; 7.规则和条件尽可能的少,以获取最大实用性和灵活性。 如果你想知道更多,点击www.xml.org或是www.w3.org/XML/1999/XML-in-10-points了解相关细节。
xml样例
下面是在样例程序中使用的一个xml样例文档:
<?xml version="1.0" encoding="utf-8" ?> 
<PurchaseOrder>
<Customer id="123"/>
<Item SKU="1234" Price="4.56" Quantity="1"/>
<Item SKU="1235" Price="4.58" Quantity="2"/>
</PurchaseOrder>
在com中加载xml
最简单的使用xml的程序是一个控制台程序。在Visual Studio.NET中创建的过程如下:选择文件-〉新建-〉工程---〉vc++工程-〉win32程序。将程序的设置改为控制台程序。(使用vc++ 6的:选择文件-〉新建工程-〉win32程序。程序的设置改为控制台程序。你可以使用一样的代码)。我将我的文件命名为XMLCOM,因此my _tmain()函数保存在XMLCOM.cpp文件中。下面是它的内容:
#include "stdafx.h"
#import "msxml4.dll" 
using namespace MSXML2;
#include <iostream>
using std::cout;
using std::endl;
int _tmain(int argc, _TCHAR* argv[])
{
  CoInitialize(NULL);
  { //extra braces for scope only

    MSXML2::IXMLDOMDocumentPtr
               xmlDoc("MSXML2.DOMDocument.4.0");
    xmlDoc->async = false;
    bool ret = xmlDoc->load("sample.xml");

    if ( ret)
    {
      cout << "Document loaded ok." << endl;
    }
    else
    {
       cout << "load problem" << endl;
    }
  }
  CoUninitialize();

  return 0;
}
你看到我使用#import导入com库,以让我的程序能够最简单。我在开头调用了CoInitialize()使com准备好,在最后又调用CoUninitialize()。中间段我创建了一个堆栈com对象的实例。它看起来像一个指针,但实际上是一个对象,它使用了我用#import声明创建的模板。如果溢出的话,它会自我清除,因此我以另外一系列的括号将它封装起来,以便我能够在调用CoUninitialize()之前将它送出。这个部分对使用#import节省时间的com程序员而言是很熟悉的。 哪里是使用xml的部分?对load()的调用。这个函数使用一个URL或是相关的文件名字,从url或是文件中读取xml内容。如果有问题,比如找不到文件或xml格式不对,它返回false。一行代码导入了所有的xml内容,现在你就能用它做些什么了。
一个简单算法
以下是样例代码:
double total = 0;
cout << "Document loaded ok." << endl;
MSXML2::IXMLDOMNodeListPtr items =
         xmlDoc->getElementsByTagName("Item");
long numitems;
items->get_length(&numitems);
for (int i=0;i<numitems;i++)
{
  MSXML2::IXMLDOMNodePtr item ;
  items->get_item(i, &item);
  double price =
   item->attributes->getNamedItem("Price")->GetnodeValue();
  double qty =
    item->attributes->getNamedItem("Quantity")->GetnodeValue();
  total += price * qty;
}
cout << "Purchase Order total is $" << total << endl
我将代码放在(如果可以的话)ret块中,替换掉以前那个位置上的output声明。你看到它借用了很多DOM API的函数: 1.getElementsbyTagName() 返回所有<Item>元素列表; 2.get_length()获取列表的长度; 3.get_item()从列表中获得一个item; 4.attributes是item的一个属性,是item所有的属性列表。列表为映射或是查询表格的形式; 5.getNameItem()利用所提供的字符串查询映射中的条目; 6.getNodeValue()摘要属性内容,以便你能在简单算法中使用; 我如何记住所有这一切?我并没有。Intellisense对我的帮助无可估量。我知道getElementsbyTagName(),它是一个所有xml处理器都支持的标准xml函数。帮助文件告诉我它返回什么:一个XMLDOMNode列表,我在末尾附加Ptr,这样我能够获得由#import创建的helper类。接下来就只是一个键入的问题了,以及看看Intellisense都提供了些什么。 在你使用#import时,所衍生出的类中有一个有趣的惯例。以get_开头的函数获取某一已被定位的对象的地址,并赋其一个值,比如这样:
items->get_lengt&numitems);
以get开头(没有下划线)则只是返回你所需要的, 比如:
double qty =
item->attributes->getNamedItem("Quantity")->GetnodeValue();
一个类通常都支持以上两类函数,但是帮助文档中的c++例子只告诉你采用指针的那一类。我想C++程序员一般都不愿意将结果或是其他某些东西返回给我们。无论如何,记住存在着这样两类函数。运行这个程序时会显示:
Document loaded ok.
Purchase Order total is $13.7 
现在知道运行xml并且利用其做些什么的简单性了吧。你能够将xml转化成其他很多格式――html,或是其他。你能够很轻松的将其输出到一个文件或是屏幕上:
_bstr_t text =  xmlDoc->Getxml();
char* printable = text;
cout << printable << endl;
上面的代码使用helper类_bstr_t,它封装了一个BSTR并且提供一个char转换函数。尽管如此,转化函数必须要调用――你不能仅仅交给BSTR处理,不过这已经是相当灵活方便了。我推荐你只要有机会就用用xml。它的确是在改变一切。 如果你从不是com程序员,对HRESULTs感到全身麻痹,想到BSTR会颤抖,振作起来!下次你会看到以.net的方式应该怎么做。 (责任编辑 Sunny)   
加载更多

专题访谈

合作站点
stat