bool CMarkup::RestorePos( MCD_CSTR szPosName = "", int nMap = 0 );
Call RestorePos
to return to a position previously saved with the SavePos method. The current position consists of the parent, main and child positions. The RestorePos
method returns false
if there is no saved position by the name szPosName
. When you resume navigating at the restored position, both the main position and the child position will be where they were when they were saved.
Update September 27, 2008: The optional nMap
argument is used for additional maps. You can have any number of maps to save and restore positions of different sets of indexing information. The default map is 0. For lookup examples, and more about using multiple maps, see SetMapSize.
SavePos
is implemented with a map of name position pairs. This is a quick lookup, but it is not the efficient way to navigate around in CMarkup when you don't need a lookup. You can tell a good lookup scenario when you already have unique ID values for elements in your document.
In the following example, the position of the Total and Data elements are saved with SavePos
. While looping through the data values, we switch back and forth between the Total position and the Data position using RestorePos
, and the Total is updated as the values are added under Data.
int anSomeData[] = { 10, 30, 50, 20, 90, 0 }; CMarkup xml; xml.AddElem( _T("SavePosExample") ); xml.IntoElem(); xml.AddElem( _T("Total") ); xml.SavePos( _T("Total") ); xml.AddElem( _T("Data") ); xml.SavePos( _T("Data") ); for ( int nD=0; anSomeData[nD]; ++nD ) { xml.RestorePos( _T("Total") ); xml.SetData( _ttoi(xml.GetData()) + anSomeData[nD] ); xml.RestorePos( _T("Data") ); xml.AddChildElem( _T("Value"), anSomeData[nD] ); }
This is the resulting XML document, indented for illustration.
<SavePosExample>
<Total>200</Total>
<Data>
<Value>10</Value>
<Value>30</Value>
<Value>50</Value>
<Value>20</Value>
<Value>90</Value>
</Data>
</SavePosExample>
But this is not a lookup scenario, so there is a more efficient way to implement the same set of operations without SavePos
and RestorePos
. By using known sibling/parent/child relationships, the example above could be re-written as follows.
int anSomeData[] = { 10, 30, 50, 20, 90, 0 }; CMarkup xml; xml.AddElem( _T("SavePosExample") ); xml.IntoElem(); xml.AddElem( _T("Total") ); xml.AddElem( _T("Data") ); for ( int nD=0; anSomeData[nD]; ++nD ) { xml.ResetMainPos(); xml.FindElem(); xml.SetData( _ttoi(xml.GetData()) + anSomeData[nD] ); xml.FindElem(); xml.AddChildElem( _T("Value"), anSomeData[nD] ); }
It is very efficient to call ResetMainPos and FindElem, because they are simple linked list operations and you avoid the overhead of looking up a stored position and name.
Thanks for pointing this out. With CMarkup release 8.0, saved positions are removed when the element or containing element is removed (prior to 8.0 restoring to an invalid position causes bad problems). Now RestorePos
can even be used as a way of discovering whether or not the element is still in the document. This is a feature that makes RestorePos
effective in scenarios that GotoElemIndex is not.
Jonathan White 07-Oct-2004
I believe I've discovered a bug/feature which broke my XML. Basically, if you save a position, remove the element to which the position points and then restore the position, the class now has an invalid
m_iPos
and starts writing stuff in the wrong place.