msxml3: Fix ignorable whitespace detection in case of formatting text nodes.
This commit is contained in:
parent
cd556855ca
commit
e5261f03e6
|
@ -416,20 +416,26 @@ static void sax_characters(void *ctx, const xmlChar *ch, int len)
|
||||||
|
|
||||||
if (ctxt->node)
|
if (ctxt->node)
|
||||||
{
|
{
|
||||||
|
xmlChar cur = *(ctxt->input->cur);
|
||||||
|
|
||||||
/* Characters are reported with multiple calls, for example each charref is reported with a separate
|
/* Characters are reported with multiple calls, for example each charref is reported with a separate
|
||||||
call and then parser appends it to a single text node or creates a new node if not created.
|
call and then parser appends it to a single text node or creates a new node if not created.
|
||||||
It's not possible to tell if it's ignorable data or not just looking at data itself cause it could be
|
It's not possible to tell if it's ignorable data or not just looking at data itself cause it could be
|
||||||
a space chars that separate charrefs or similar case. We only need to skip leading and trailing spaces,
|
space chars that separate charrefs or similar case. We only need to skip leading and trailing spaces,
|
||||||
or whole node if it has nothing but space chars, so to detect leading space node->last is checked that
|
or whole node if it has nothing but space chars, so to detect leading space node->last is checked that
|
||||||
contains text node pointer if already created, trailing spaces are detected directly looking at parser input
|
contains text node pointer if already created, trailing spaces are detected directly looking at parser input
|
||||||
for next '<' opening bracket - similar logic is used by libxml2 itself.
|
for next '<' opening bracket - similar logic is used by libxml2 itself. Basically 'cur' == '<' means the last
|
||||||
|
chunk of char data, in case it's not the last chunk we check for previously added node type and if it's not
|
||||||
|
a text node it's safe to ignore.
|
||||||
|
|
||||||
Note that during domdoc_loadXML() the xmlDocPtr->_private data is not available. */
|
Note that during domdoc_loadXML() the xmlDocPtr->_private data is not available. */
|
||||||
|
|
||||||
if (!This->properties->preserving &&
|
if (!This->properties->preserving &&
|
||||||
!is_preserving_whitespace(ctxt->node) &&
|
!is_preserving_whitespace(ctxt->node) &&
|
||||||
strn_isspace(ch, len) &&
|
strn_isspace(ch, len) &&
|
||||||
(!ctxt->node->last ||
|
(!ctxt->node->last ||
|
||||||
((ctxt->node->last && (*ctxt->input->cur) == '<'))))
|
((ctxt->node->last && (cur == '<' || ctxt->node->last->type != XML_TEXT_NODE))
|
||||||
|
)))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -385,6 +385,15 @@ static const WCHAR szComplete6[] = {
|
||||||
'<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
|
'<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char complete7[] = {
|
||||||
|
"<?xml version=\"1.0\"?>\n\t"
|
||||||
|
"<root>\n"
|
||||||
|
"\t<a/>\n"
|
||||||
|
"\t<b/>\n"
|
||||||
|
"\t<c/>\n"
|
||||||
|
"</root>"
|
||||||
|
};
|
||||||
|
|
||||||
#define DECL_WIN_1252 \
|
#define DECL_WIN_1252 \
|
||||||
"<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
|
"<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
|
||||||
|
|
||||||
|
@ -4212,7 +4221,11 @@ static void test_preserve_charref(IXMLDOMDocument2 *doc, VARIANT_BOOL preserve)
|
||||||
static void test_whitespace(void)
|
static void test_whitespace(void)
|
||||||
{
|
{
|
||||||
IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
|
IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
|
||||||
|
IXMLDOMNodeList *list;
|
||||||
|
IXMLDOMElement *root;
|
||||||
VARIANT_BOOL b;
|
VARIANT_BOOL b;
|
||||||
|
HRESULT hr;
|
||||||
|
LONG len;
|
||||||
|
|
||||||
doc1 = create_document(&IID_IXMLDOMDocument2);
|
doc1 = create_document(&IID_IXMLDOMDocument2);
|
||||||
doc2 = create_document(&IID_IXMLDOMDocument2);
|
doc2 = create_document(&IID_IXMLDOMDocument2);
|
||||||
|
@ -4286,6 +4299,26 @@ static void test_whitespace(void)
|
||||||
/* text with char references */
|
/* text with char references */
|
||||||
test_preserve_charref(doc1, VARIANT_TRUE);
|
test_preserve_charref(doc1, VARIANT_TRUE);
|
||||||
test_preserve_charref(doc1, VARIANT_FALSE);
|
test_preserve_charref(doc1, VARIANT_FALSE);
|
||||||
|
|
||||||
|
/* formatting whitespaces */
|
||||||
|
hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_FALSE);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXMLDOMDocument2_loadXML(doc1, _bstr_(complete7), &b);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
ok(b == VARIANT_TRUE, "for %x\n", b);
|
||||||
|
|
||||||
|
hr = IXMLDOMDocument2_get_documentElement(doc1, &root);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
hr = IXMLDOMElement_get_childNodes(root, &list);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
len = 0;
|
||||||
|
hr = IXMLDOMNodeList_get_length(list, &len);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
ok(len == 3, "got %d\n", len);
|
||||||
|
IXMLDOMNodeList_Release(list);
|
||||||
|
IXMLDOMElement_Release(root);
|
||||||
|
|
||||||
IXMLDOMDocument2_Release(doc1);
|
IXMLDOMDocument2_Release(doc1);
|
||||||
|
|
||||||
free_bstrs();
|
free_bstrs();
|
||||||
|
|
Loading…
Reference in New Issue