最近在一个 C 程序中碰到需要将 XML 数据转换为 JSON 数据的问题,多番查找几种方法,觉得此程序刚好用到了 Linux 下的 libexslt XSLT 库,因此想直接通过 XSLT 将 XML 转为 JSON 数据。
网上已经有了现成的 XML 转 JSON 的 XSLT 程序:
http://code.google.com/p/xml2json-xslt/
下载下来的 xml2json.xslt 程序可以很方便的将标准的 XML 文件转换为 JavaScript 样式的 JSON 数据,但经过试用之后发现此程序还是有一些不足,例如:不支持转换 XML 属性,对数组支持不好等问题。
我对 xml2json.xslt 做了一些改进,包括将 XML 中的属性名转换为 JSON 子节点(节点名称为 @attr 这种特殊的样式),并且为需要明确转换为 JSON 数组的节点(即使该节点下面只包含一个同类的子节点)增加 ifArray 属性,如果 ifArray 属性值为 yes,则在转换为 JSON 强制生成数组。
这个是我修改过的 xml2json.xslt 文件:
https://gist.github.com/zohead/9688858
Linux 系统可以方便的使用 xsltproc 命令将 XML 转换为 JSON,运行下面的命令就会直接将转换出来的 JSON 数据打印到标准输出中:
xsltproc xml2json.xslt test.xml
下面主要介绍如何在 Linux 中编程使用 libexslt 库将 XML 转换为 JSON 数据,有关 libexslt 库的介绍请参考这里:http://xmlsoft.org/libxslt/EXSLT/,可惜 libexslt 并没有详细的介绍文档,连网上的例子都很少。
实例程序:
int xslProc(const char *xslfile, const char *xmlfile, const char *outfile, const char *xmlstr, char *lpbuf, size_t bufsize){
xsltStylesheetPtr cur = NULL;
xmlDocPtr doc = NULL, res = NULL;
int iRet = -1;
if (xslfile == NULL || !xslfile[0] || ((xmlfile == NULL || !xmlfile[0]) && (xmlstr == NULL || !xmlstr[0])) || ((outfile == NULL || !outfile[0]) && lpbuf == NULL))
return -1;
exsltRegisterAll();
xmlInitParser();
xmlSubstituteEntitiesDefault(1);
xmlLoadExtDtdDefaultValue = 1;
cur = xsltParseStylesheetFile((const xmlChar *)xslfile);
if (cur) {
if (xmlfile)
doc = xmlParseFile(xmlfile);
else
doc = xmlParseMemory(xmlstr, strlen(xmlstr));
if (doc) {
res = xsltApplyStylesheet(cur, doc, NULL);
if (res) {
if (outfile)
iRet = xsltSaveResultToFilename(outfile, res, cur, 0);
else {
char *out = NULL;
int outlen = 0;
iRet = xsltSaveResultToString((xmlChar **)&out, &outlen, res, cur);
if (out) {
if (iRet == 0) strncpy(lpbuf, out, bufsize);
free(out);
}
}
xmlFreeDoc(res);
} else
iRet = 1;
xmlFreeDoc(doc);
} else
iRet = 2;
xsltFreeStylesheet(cur);
} else
iRet = 3;
xsltCleanupGlobals();
xmlCleanupParser();
return iRet;}
程序传入 XSLT 文件名,支持 XML 字符串、XML 文件以及输出到文件及保存到字符串的方式。
具体实现方法还是比较简单的,使用 Linux 的 libexslt 库解析 XSLT 文件(xsltParseStylesheetFile),libxml 库来解析 XML 文件(xmlParseFile 和 xmlParseMemory 函数),使用 libexslt 库应用 XSLTstylesheet(xsltApplyStylesheet),保存结果数据使用 xsltSaveResultToFilename 和 xsltSaveResultToString 函数,程序中需要特别注意的就是 libxml 和 libexslt 库中众多的初始化和释放操作。
本文分享自 nginx遇上redis 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!