我似乎無法得到的libxml2正確地從內存解析DTD:DTD中包含指向w3c.org外部XHTML實體引用。鏈接正在工作,瀏覽器加載他們的內容就好了。但是,即使從xmlIOParseDTD
函數返回成功狀態,libxml2也會報告加載HTTP資源失敗。的libxml2:xmlIOParseDTD:I/O警告:加載失敗HTTP資源
下面是最小的測試來重現問題:
#include "libxml/xmlreader.h"
#include <string>
#include <fstream>
#include <iostream>
int main()
{
// Read DTD from file
std::ifstream f;
f.open("enml2.dtd");
if (!f.is_open()) {
std::cerr << "Can't open enml2.dtd file" << std::endl;
return 1;
}
std::string enml;
std::string line;
while(getline(f, line))
{
enml += line;
}
f.close();
// Init parser options
xmlInitParser();
xmlSubstituteEntitiesDefault(1);
xmlLoadExtDtdDefaultValue = 1;
// Parse DTD from memory
xmlParserInputBufferPtr pBuf = xmlParserInputBufferCreateMem(enml.c_str(), enml.size(),
XML_CHAR_ENCODING_UTF8);
if (!pBuf) {
std::cerr << "can't allocate input buffer for dtd validation" << std::endl;
return 2;
}
xmlDtdPtr pDtd = xmlIOParseDTD(NULL, pBuf, XML_CHAR_ENCODING_UTF8);
if (!pDtd) {
std::cerr << "can't parse dtd from buffer" << std::endl;
return 3;
}
std::cout << "Successfully parsed DTD" << std::endl;
xmlFreeDtd(pDtd);
return 0;
}
所提到的enml2.dtd
文件可以從這裏下載:(在我的情況在Linux上)http://xml.evernote.com/pub/enml2.dtd
體形:
g++ -I/usr/include/libxml2 main.cpp -o libxml2-test -lxml2
運行:
./libxml2-test
I/O warning : failed to load HTTP resource
n 1 for XHTML//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">%HTMLlat1;
^
%HTMLlat1;
^
I/O warning : failed to load HTTP resource
for XHTML//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">%HTMLsymbol;
^
%HTMLsymbol;
^
I/O warning : failed to load HTTP resource
for XHTML//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">%HTMLspecial;
^
%HTMLspecial;
^
Successfully parsed DTD
的libxml2的使用的版本是2.9.1+dfsg1-3ubuntu4.4
,我對Linux Mint的17(對應到Ubuntu 14.04)。
更新:我在OS X 10.9上觀察與libxml2 2.9.0相同的東西。此外,xmllint
命令行實用程序無法以與示例代碼完全相同的方式獲取這些外部條目,即使我使用--loaddtd
選項顯式允許獲取外部DTD。要麼我真的錯過了它應該如何工作,或者我遇到了libxml2的錯誤。