c++ - 在 c++ 中使用 vtd-xml 时如何摆脱 EOFException?
问题描述
我正在编写一个程序来处理 C++ 中的旧数据集。我已经设法使用James Clark 的 sx 工具将文件从 sgml 转换为 xml 。由于我过去曾在 Matlab(基于 java)中使用 vtd-xml,并且由于 vtd-xml 具有 c++ 端口,因此我决定将其用于我的项目。我正在使用vtd-xml 2.12 版,因为那是我能找到的最新版本的 c++ 端口。我设法通过将 wcsdup 的所有调用更改为 _wcsdup并使用_CRT_SECURE_NO_WARNINGS来使用 Visual Studio 2019 编译它预处理器定义。我下面的程序似乎给出了正确的输出,但在解析 xml 文件期间它也会引发异常(下面还有一个测试 xml 文件)。例外是EOFException。我没有看到我的 xml 文件有任何明显错误,并且使用下面的测试 xml 重现了该错误,这不是我从 sgml 转换的。我的直觉是,如果 c++ 端口中存在错误,那么在谷歌搜索 vtd-xml EOFException 时会更容易找到有关它的信息。因此,在我看来,我为使其编译所做的更改可能是罪魁祸首,但我不知道如何摆脱异常。任何想法都会受到欢迎。如果涉及到它,如果它是免费的,我愿意为我的程序使用不同的 xml 库。
我的代码:
#include <iostream>
#include <fstream>
#include "VTDGen.h"
#include "autoPilot.h"
#include "customTypes.h"
using namespace std;
using namespace com_ximpleware;
int main() {
ifstream xml(".\\cd_catalog_short.xml", ios::binary | ios::ate);
ifstream::pos_type pos = xml.tellg();
long int length = static_cast<long int>(pos);
char* pChars = new char[length];
xml.seekg(0, ios::beg);
xml.read(pChars, pos);
xml.close();
UCSChar node_path[] = L"/CATALOG/CD/TITLE";
UCSChar* title;
VTDGen vg;
vg.setDoc(pChars, length);
vg.parse(false);
AutoPilot ap;
ap.selectXPath(node_path);
VTDNav* vn = vg.getNav();
ap.bind(vn);
while (ap.evalXPath() != -1) {
int ind = vn->getText();
if (ind != -1) {
title = vn->toNormalizedString(ind);
wcout << title << endl;
delete[] title;
}
}
return 0;
}
一个测试xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<CATALOG>
<CD>
<TITLE>For the good times</TITLE>
<ARTIST>Kenny Rogers</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>Mucik Master</COMPANY>
<PRICE>8.70</PRICE>
<YEAR>1995</YEAR>
</CD>
<CD>
<TITLE>Big Willie style</TITLE>
<ARTIST>Will Smith</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1997</YEAR>
</CD>
<CD>
<TITLE>Tupelo Honey</TITLE>
<ARTIST>Van Morrison</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>Polydor</COMPANY>
<PRICE>8.20</PRICE>
<YEAR>1971</YEAR>
</CD>
</CATALOG>
我的程序输出:
在 em.exe 中的 0x00007FF96A36A839 处引发异常:Microsoft C++ 异常:com_ximpleware::EOFException 在内存位置 0x0000005498B6F350。
为了美好时光
大威利风格
图珀洛蜂蜜
C:\Users\Joe\source\repos\em\x64\Release\em.exe(进程 16308)以代码 0 退出。
要在调试停止时自动关闭控制台,请启用工具->选项->调试->调试停止时自动关闭控制台。
按任意键关闭此窗口。. .
解决方案
vtd-xml 似乎使用 EOFException 更像是一个信号,而不是真正的错误状态。我通过运行程序的 java 版本消除了错误来自为使其在 Visual Studio (C++) 中编译而进行的更改的可能性。这使用 vtd-xml (2.13-4-java) 的最新 java 版本,它仍然捕获 EOFException。如果我一直通过控制台而不是 Visual Studio IDE 运行 c++ 程序,我可能永远不会知道该异常。
这是java代码:
/*
* Copyright (C) 2002-2011 XimpleWare, info@ximpleware.com
*/
import com.ximpleware.*;
import com.ximpleware.xpath.*;
import java.io.*;
public class Tester {
public static void main(String argv[]){
VTDGen vg = new VTDGen();
if (vg.parseFile("./cd_catalog_short.xml",false)){
try {
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/CATALOG/CD/TITLE");
int result = -1;
int count = 0;
while((result = ap.evalXPath())!=-1){
System.out.print(""+result+" ");
System.out.print("Element name ==> "+vn.toString(result));
int t = vn.getText(); // get the index of the text (char data or CDATA)
if (t!=-1)
System.out.println(" Text ==> "+vn.toNormalizedString(t));
System.out.println("\n ============================== ");
count++;
}
System.out.println("Total # of element "+count);
}
catch (NavException e){
System.out.println(" Exception during navigation "+e);
}
catch (XPathParseException e){
System.out.println(" Exception during parse "+e);
}
catch (XPathEvalException e){
System.out.println(" Exception during xpath evaluation "+e);
}
}
}
}
这是 jdb 中的程序输出:
jdb -classpath .;ximpleware-2.13-4-java 测试器
正在初始化 jdb ...
捕获 com.ximpleware.EOFException
推迟所有 com.ximpleware.EOFException。它将在加载类后设置。
跑
运行测试器
设置未捕获的 java.lang.Throwable 设置延迟未捕获的 java.lang.Throwable
VM 已启动:设置延迟所有 com.ximpleware.EOFException
发生异常:com.ximpleware.EOFException(在:com.ximpleware.VTDGen.parse(),line=2,663 bci=1,597)"thread=main",com.ximpleware.VTDGen$UTF8Reader.getChar(),line =774 bci=24 774 抛出 e;
主要[1]续
7 元素名称 ==> TITLE Text ==> 美好时光
===============================
20 元素名称 ==> 标题文字 ==> 大威利风格
===============================
33 元素名称 ==> TITLE 文本 ==> Tupelo Honey
===============================
元素 3 的总数
应用程序退出
推荐阅读
- php - 每次我在 PHP 中使用 Bootstrap 滑块单击提交按钮时如何设置计数器
- php - 使用 .htaccess 为 2 个参数重写 URL,其中 1 个作为页面,第二个作为 $_GET 值
- java - Java 中的字符集返回 UTF-8,但字符位于 Windows-1252 中
- maxima - Maxima 中的 cspline 给我一个结果,表明 Maxima 中的错误
- git - 由于我已经删除了一个大文件,无法推送到 GitHub
- python - 具有使用的功能之一和条件的 Keras 自定义损失
- networking - 如何将 Service Fabric Mesh 应用程序放入虚拟网络
- r - 如何防止 downloadHandler 提示用户输入保存位置?我希望它自动保存到指定位置而不提示
- python - 用 gensim 加载 Glove 向量的一部分
- mongodb - $and 运算符总是返回 true,即使我认为它应该是 false