diff --git a/uppsrc/Core/XML.cpp b/uppsrc/Core/XML.cpp index b27d3373e..43a899799 100644 --- a/uppsrc/Core/XML.cpp +++ b/uppsrc/Core/XML.cpp @@ -556,6 +556,24 @@ void XmlParser::PassTagE(const char *tag) SkipEnd(); } +bool XmlParser::TagElseSkip(const char *tag) +{ + if(Tag(tag)) + return true; + Skip(); + return false; +} + +bool XmlParser::LoopTag(const char *tag) +{ + while(!End()) { + if(Tag(tag)) + return true; + Skip(); + } + return false; +} + VectorMap XmlParser::PickAttrs() pick_ { if(!IsNull(attr1)) diff --git a/uppsrc/Core/XML.h b/uppsrc/Core/XML.h index 5d2ab3481..0eed66e8f 100644 --- a/uppsrc/Core/XML.h +++ b/uppsrc/Core/XML.h @@ -117,6 +117,8 @@ public: void PassEnd(); bool TagE(const char *tag); void PassTagE(const char *tag); + bool TagElseSkip(const char *tag); + bool LoopTag(const char *tag); int GetAttrCount() const { return attr.GetCount() + !IsNull(attr1); } String GetAttr(int i) const { return i ? attr.GetKey(i - 1) : attr1; } diff --git a/uppsrc/Core/src.tpp/XmlParser$en-us.tpp b/uppsrc/Core/src.tpp/XmlParser$en-us.tpp index 8db2e2a5a..4e3e4adaf 100644 --- a/uppsrc/Core/src.tpp/XmlParser$en-us.tpp +++ b/uppsrc/Core/src.tpp/XmlParser$en-us.tpp @@ -96,6 +96,23 @@ t]_[@(0.0.255) char]_`*[*@3 tag])&] [s2;%% Calls PassTag([%-*@3 tag]) and then PassEnd(). In other words, requires to advance over element with empty content.&] [s3;%% &] +[s4; &] +[s5;:XmlParser`:`:TagElseSkip`(const char`*`): [@(0.0.255) bool]_[* TagElseSkip]([@(0.0.255) c +onst]_[@(0.0.255) char]_`*[*@3 tag])&] +[s2;%% If call Tag([%-*@3 tag]).returns true. Otherwise calls Skip +and returns else. This is a shortcut to relatively common construct + [*C if(Tag(][%-*C@3 tag][*C )) `{ ... `} else Skip()][* ;]&] +[s3;%% &] +[s4; &] +[s5;:XmlParser`:`:LoopTag`(const char`*`): [@(0.0.255) bool]_[* LoopTag]([@(0.0.255) const]_ +[@(0.0.255) char]_`*[*@3 tag])&] +[s2;%% If End call returns true, returns false. If call to Tag([%-*@3 tag]) +returns true, returns true. Otherwise it calls Skip and repeats. +This is useful if we are only interested in just one type of +subtag of current level, e.g.: [*C while(LoopTag(`"foo`")) `{ ... +`}] `- is an equivalent of common construct [*C while(!End()) +if(Tag(][%-*C@3 tag][*C )) `{ ... `} else Skip();]&] +[s3;%% &] [s4;%% &] [s5;:XmlParser`:`:GetAttrCount`(`)const: [@(0.0.255) int]_[* GetAttrCount]()_[@(0.0.255) co nst]&] @@ -106,6 +123,11 @@ nst]&] ])_[@(0.0.255) const]&] [s2;%% Returns the name of attribute [%-*@3 i ]of the last start`-tag.&] [s3;%% &] +[s4; &] +[s5;:XmlParser`:`:IsAttr`(const char`*`)const: [@(0.0.255) bool]_[* IsAttr]([@(0.0.255) con +st]_[@(0.0.255) char]_`*[*@3 id])_[@(0.0.255) const]&] +[s2;%% Returns true if [%-*@3 id] an attribute of the last start`-tag.&] +[s3;%% &] [s4;%% &] [s5;:XmlParser`:`:operator`[`]`(int`)const: [_^String^ String]_[* operator`[`]]([@(0.0.255) i nt]_[*@3 i])_[@(0.0.255) const]&]