xerces_3_1 能够在评论和处理说明中创建无效的 xml
xerces_3_1 is able to create invalid xml at comments & processing instructions
我在使用 xerces-dom 库时遇到问题:
当您向 xml-树添加评论时,例如:
DOMDocument* doc = impl->createDocument(0, L"root", 0);
DOMElement* root = doc->getDocumentElement();
DOMComment* com1 = doc->createComment(L"SetA -- DataA");
DOMComment* com2 = doc->createComment(L"SetB -- DataB");
doc->insertBefore(com1, root);
doc->insertBefore(com2, root);
这将创建以下 xml-树:
<?xml version="1.0" encoding="UTF-8" standalone="false"?>
<!--SetA -- DataA-->
<!--SetB -- DataB-->
<root/>
确实无效xml.
同样可以通过使用?>
作为数据来处理指令:
DOMProcessingInstruction procInstr = doc->createProcessingInstruction(L"target", L"?>");
我的问题:
有什么方法可以配置 xerces 不创建此类评论,还是我必须自己检查这些内容?
还有我的另一个问题:为什么不能总是转义像 <>&'"
这样的字符,甚至在注释和处理指令中,以避免此类问题?
DOM文档不是 XML 文档。它应该代表一个,但可以想象一个有效的 DOM 可能无法序列化为一个有效的 XML 文档(相反的情况应该不太可能)。确实这似乎是这里的情况:
Level 1 和 Level2 两个规范都没有提到这个,但是 Level 3 DOM specification 添加了关于 DOM评论界面的这句话:
No lexical check is done on the content of a comment and it is therefore possible to have the character sequence "--" (double-hyphen) in the content, which is illegal in a comment per section 2.5 of [XML 1.0]. The presence of this character sequence must generate a fatal error during serialization.
所以 Xerces 在 DOM 级别 3 规范内运行,即使它接受其中带有 '--' 的注释,只要它在你去序列化它时爆炸。
情况不太好,但这是有道理的,因为 DOM 最初是为了表示 XML 已读入的文档,而不是创建新文档。所以它可以代表什么是自由的。适合阅读 - DOM评论可以代表 XML 文档可以代表的任何内容(甚至更多),但有点烦人的是当您 createComment()
.
检查 DOMDocumentImpl.cpp 我们看到:
DOMComment *DOMDocumentImpl::createComment(const XMLCh *data)
{
return new (this, DOMMemoryManager::COMMENT_OBJECT) DOMCommentImpl(this, data);
}
而在 DOMCommentImpl.cpp 中我们只有:
DOMCommentImpl::DOMCommentImpl(DOMDocument *ownerDoc, const XMLCh *dat)
: fNode(ownerDoc), fCharacterData(ownerDoc, dat)
{
fNode.setIsLeafNode(true);
}
最后我们在 DOMCharacterDataImpl.cpp 中看到没有预先验证的机会 - 它只是保存用户提供的字符串而不检查它。
DOMCharacterDataImpl::DOMCharacterDataImpl(DOMDocument *doc, const XMLCh *dat)
{
fDoc = (DOMDocumentImpl*)doc;
XMLSize_t len=XMLString::stringLen(dat);
fDataBuf = fDoc->popBuffer(len+1);
if (!fDataBuf)
fDataBuf = new (fDoc) DOMBuffer(fDoc, len+15);
fDataBuf->set(dat, len);
}
可悲的是,没有 Xerces 没有一个选项,甚至没有一个很好的钩子来为你检查这个。 而且因为 3 级规范似乎要求 "No lexical check is done" , 添加一个可能是不合法的。
第二个问题的答案更容易回答:因为这就是他们想要的定义它的方式。参见 XML 1.1 spec 例如:
Comments
[15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
PI 也类似。
语法根本不允许转义。似乎是对的:巴洛克风格 and broke.
也许有一种方法可以捕获序列化或规范化的错误,但我无法确认 Xerces 3.1 是否可以。为了安全起见,我认为最好的方法是在创建节点之前包装 createComment()
并检查它,或者遍历树并自己检查它。
我在使用 xerces-dom 库时遇到问题:
当您向 xml-树添加评论时,例如:
DOMDocument* doc = impl->createDocument(0, L"root", 0);
DOMElement* root = doc->getDocumentElement();
DOMComment* com1 = doc->createComment(L"SetA -- DataA");
DOMComment* com2 = doc->createComment(L"SetB -- DataB");
doc->insertBefore(com1, root);
doc->insertBefore(com2, root);
这将创建以下 xml-树:
<?xml version="1.0" encoding="UTF-8" standalone="false"?>
<!--SetA -- DataA-->
<!--SetB -- DataB-->
<root/>
确实无效xml.
同样可以通过使用?>
作为数据来处理指令:
DOMProcessingInstruction procInstr = doc->createProcessingInstruction(L"target", L"?>");
我的问题:
有什么方法可以配置 xerces 不创建此类评论,还是我必须自己检查这些内容?
还有我的另一个问题:为什么不能总是转义像 <>&'"
这样的字符,甚至在注释和处理指令中,以避免此类问题?
DOM文档不是 XML 文档。它应该代表一个,但可以想象一个有效的 DOM 可能无法序列化为一个有效的 XML 文档(相反的情况应该不太可能)。确实这似乎是这里的情况:
Level 1 和 Level2 两个规范都没有提到这个,但是 Level 3 DOM specification 添加了关于 DOM评论界面的这句话:
No lexical check is done on the content of a comment and it is therefore possible to have the character sequence "--" (double-hyphen) in the content, which is illegal in a comment per section 2.5 of [XML 1.0]. The presence of this character sequence must generate a fatal error during serialization.
所以 Xerces 在 DOM 级别 3 规范内运行,即使它接受其中带有 '--' 的注释,只要它在你去序列化它时爆炸。
情况不太好,但这是有道理的,因为 DOM 最初是为了表示 XML 已读入的文档,而不是创建新文档。所以它可以代表什么是自由的。适合阅读 - DOM评论可以代表 XML 文档可以代表的任何内容(甚至更多),但有点烦人的是当您 createComment()
.
检查 DOMDocumentImpl.cpp 我们看到:
DOMComment *DOMDocumentImpl::createComment(const XMLCh *data)
{
return new (this, DOMMemoryManager::COMMENT_OBJECT) DOMCommentImpl(this, data);
}
而在 DOMCommentImpl.cpp 中我们只有:
DOMCommentImpl::DOMCommentImpl(DOMDocument *ownerDoc, const XMLCh *dat)
: fNode(ownerDoc), fCharacterData(ownerDoc, dat)
{
fNode.setIsLeafNode(true);
}
最后我们在 DOMCharacterDataImpl.cpp 中看到没有预先验证的机会 - 它只是保存用户提供的字符串而不检查它。
DOMCharacterDataImpl::DOMCharacterDataImpl(DOMDocument *doc, const XMLCh *dat)
{
fDoc = (DOMDocumentImpl*)doc;
XMLSize_t len=XMLString::stringLen(dat);
fDataBuf = fDoc->popBuffer(len+1);
if (!fDataBuf)
fDataBuf = new (fDoc) DOMBuffer(fDoc, len+15);
fDataBuf->set(dat, len);
}
可悲的是,没有 Xerces 没有一个选项,甚至没有一个很好的钩子来为你检查这个。 而且因为 3 级规范似乎要求 "No lexical check is done" , 添加一个可能是不合法的。
第二个问题的答案更容易回答:因为这就是他们想要的定义它的方式。参见 XML 1.1 spec 例如:
Comments
[15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
PI 也类似。
语法根本不允许转义。似乎是对的:巴洛克风格 and broke.
也许有一种方法可以捕获序列化或规范化的错误,但我无法确认 Xerces 3.1 是否可以。为了安全起见,我认为最好的方法是在创建节点之前包装 createComment()
并检查它,或者遍历树并自己检查它。