diff --git a/gb.xml/src/CReader.cpp b/gb.xml/src/CReader.cpp index 72fe3c0f7..c5a8be8ef 100644 --- a/gb.xml/src/CReader.cpp +++ b/gb.xml/src/CReader.cpp @@ -141,10 +141,31 @@ if(!THIS->foundNode->type == Node::ElementNode) return; Attribute *attr = XMLElement_GetAttribute((Element*)(THIS->foundNode), STRING(name), LENGTH(name)); +if (!attr) +{ + GB.Error("No such attribute"); + return; +} + GB.ReturnNewString(attr->attrValue, attr->lenAttrValue); END_METHOD +BEGIN_METHOD(CReaderNodeAttr_Exist, GB_STRING name) + +if(!THIS->foundNode || THIS->state == READ_END_CUR_ELEMENT) +{ + return; +} + +if(!THIS->foundNode->type == Node::ElementNode) return; + +Attribute *attr = XMLElement_GetAttribute((Element*)(THIS->foundNode), STRING(name), LENGTH(name)); + +GB.ReturnBoolean(!!attr); + +END_METHOD + BEGIN_PROPERTY(CReaderNodeAttr_count) if(!THIS->foundNode || THIS->state == READ_END_CUR_ELEMENT) @@ -353,6 +374,7 @@ GB_DESC CReaderNodeAttributesDesc[] = GB_METHOD("_get", "s", CReaderNodeAttr_get, "(Name)s"), GB_METHOD("_next", "s", CReaderNodeAttr_next, ""), + GB_METHOD("Exist", "b", CReaderNodeAttr_Exist, "(Name)s"), GB_PROPERTY_READ("Count", "i", CReaderNodeAttr_count), GB_PROPERTY_READ("Name", "i", CReaderNodeAttr_name), GB_PROPERTY_READ("Value", "i", CReaderNodeAttr_value), diff --git a/gb.xml/src/reader.cpp b/gb.xml/src/reader.cpp index 954cb6c82..4ac0b76cd 100644 --- a/gb.xml/src/reader.cpp +++ b/gb.xml/src/reader.cpp @@ -138,7 +138,21 @@ int Reader::ReadChar(char car) return 0; } - if(car == '<' && !inComment)//Début de tag + /* [T. Boege, 02 Apr 2017]: Reset specialTagLevel, which tries to recognise a sequence + * of characters, when this sequence is interrupted, so that e.g. + * does *not* finish the CDATA tag at ]x]>. We want a literal ]]>. */ + if (inCDATA) + { + if (specialTagLevel > CDATA_TAG_STARTCHAR_8 && car != ']' && car != '>') + specialTagLevel = CDATA_TAG_STARTCHAR_8; + } + if (inComment) + { + if (specialTagLevel > COMMENT_TAG_STARTCHAR_3 && car != '-' && car != '-') + specialTagLevel = COMMENT_TAG_STARTCHAR_3; + } + + if(car == '<' && !inComment && !inCDATA)//Début de tag { if(inTag)//Si on est déjà dans un tag { @@ -166,7 +180,7 @@ int Reader::ReadChar(char car) return NODE_TEXT; } } - else if(car == '>' && inTag && !inEndTag && !inComment)//Fin de tag (de nouvel élément) + else if(car == '>' && inTag && !inEndTag && !inComment && !inCDATA)//Fin de tag (de nouvel élément) { DESTROYPARENT(foundNode); //UNREF(foundNode); @@ -195,12 +209,12 @@ int Reader::ReadChar(char car) this->state = NODE_ELEMENT; return NODE_ELEMENT; } - else if(isWhiteSpace(car) && inTag && inTagName && !inComment)// Fin de tagName + else if(isWhiteSpace(car) && inTag && inTagName && !inComment && !inCDATA)// Fin de tagName { inTagName = false; XMLElement_RefreshPrefix((Element*)curNode); } - else if(isNameStartChar(car) && inTag && !inTagName && !inEndTag && !inAttrVal && !inAttrName && !inComment)//Début de nom d'attribut + else if(isNameStartChar(car) && inTag && !inTagName && !inEndTag && !inAttrVal && !inAttrName && !inComment && !inCDATA)//Début de nom d'attribut { if(attrName && attrVal) { @@ -220,16 +234,16 @@ int Reader::ReadChar(char car) *attrName = car; lenAttrName = 1; } - else if(car == '=' && inAttrName && !inComment)//Fin du nom d'attribut + else if(car == '=' && inAttrName && !inComment && !inCDATA)//Fin du nom d'attribut { inAttrName = false; } - else if((car == '\'' || car == '"') && inAttr && !inAttrVal && !inComment)//Début de valeur d'attribut + else if((car == '\'' || car == '"') && inAttr && !inAttrVal && !inComment && !inCDATA)//Début de valeur d'attribut { inAttrVal = true; attrVal = 0; } - else if((car == '\'' || car == '"') && inAttr && inAttrVal && !inComment)//Fin de valeur d'attribut + else if((car == '\'' || car == '"') && inAttr && inAttrVal && !inComment && !inCDATA)//Fin de valeur d'attribut { XMLElement_AddAttribute(((Element*)curNode), attrName, lenAttrName, attrVal, lenAttrVal); @@ -240,7 +254,7 @@ int Reader::ReadChar(char car) this->state = READ_ATTRIBUTE; return READ_ATTRIBUTE; } - else if(car == '/' && inTag && !inAttrVal && !inComment)//Self-closed element + else if(car == '/' && inTag && !inAttrVal && !inComment && !inCDATA)//Self-closed element { inTag = false; inTagName = false; @@ -256,13 +270,13 @@ int Reader::ReadChar(char car) depth++; return NODE_ELEMENT; } - else if(car == '/' && inNewTag && !inComment)//C'est un tag de fin + else if(car == '/' && inNewTag && !inComment && !inCDATA)//C'est un tag de fin { inEndTag = true; inNewTag = false; inTag = true; } - else if(car == '>' && inEndTag && !inComment)//La fin d'un tag de fin + else if(car == '>' && inEndTag && !inComment && !inCDATA)//La fin d'un tag de fin { inTag = false; inEndTag = false; @@ -350,7 +364,7 @@ int Reader::ReadChar(char car) return NODE_CDATA; } //Caractère "-" de début de commentaire - else if(inCommentTag && car == '-' && specialTagLevel >= COMMENT_TAG_STARTCHAR_1 && specialTagLevel < COMMENT_TAG_STARTCHAR_3 && !inComment) + else if(inCommentTag && car == '-' && specialTagLevel >= COMMENT_TAG_STARTCHAR_1 && specialTagLevel < COMMENT_TAG_STARTCHAR_3 && !inComment && !inCDATA) { ++specialTagLevel; if (specialTagLevel == COMMENT_TAG_STARTCHAR_3)//Le tag