CMarkup GetOffsets Method

bool CMarkup::GetOffsets(
  int* pnStart,
  int* pnLen,
  int* pnInStart = NULL,
  int* pnInLen = NULL
  ) const;

CMarkup Developer License

GetOffsets is only in CMarkup Developer and the free XML editor  FOAL C++ scripting.

CMarkup is set apart from other XML tools by the fact that it keeps the document intact rather than storing it internally as a collection of individual nodes. And with CMarkup all whitespace is preserved. This yields great efficiencies when working together with a text editor.

The Offsets methods give you a unique opportunity to implement mechanisms that take advantage of knowing element and attribute locations in the document string. These methods were added to CMarkup (developer version only) in release 6.5 and used by the firstobject XML Editor to locate and highlight elements in the text of the document.

Offsets are counted in char (bytes) or wchar_t (2 bytes) if it is a UNICODE (wide char) build. If a multi-byte character set such as UTF-8 or far east double byte (MBCS) is in use, offsets are in bytes (character counts are not useful for this purpose anyway). For illustration look at the following XML document (with CRLFs, i.e. lines are ended with two chars \r\n). The TEST element starts at 0, and the NAME element starts at offset 10 after the two space indent. The NAME element length is 17.

<TEST>
  <NAME>John</NAME>
</TEST>

The simplest way to use GetOffsets is with only the first two arguments, since the next two are optional. The following example gets the starting offset and length of both the TEST and NAME elements:

int nStart, nLength;
xml.ResetPos();
xml.FindElem();
xml.GetOffsets( &nStart, &nLength );
// now nStart is 0 and nLength is 36
xml.IntoElem();
xml.FindElem();
xml.GetOffsets( &nStart, &nLength );
// now nStart is 10 and nLength is 17

The optional arguments provide the content start and length. Continuing from the previous code with the current main position at the NAME element, offset and length of the text data John can be determined as follows:

int nInStart, nInLength;
xml.GetOffsets( &nStart, &nLength, &nInStart, &nInLength );
// now nInStart is 16 and nInLength is 4

See the companion GetAttribOffsets method for getting the offsets of attributes, and a more involved example.

Update August 17, 2005: With release 8.1, the GetOffsets inner start (pnInStart) argument now returns equal to the start (pnStart) for empty elements. Also, GetOffsets returns offsets for non-element nodes. When the current position is a node, the start and length represent the outer edges of the node while the inner start and length represent the same data portion return by the GetData method.

 

comment posted Problem with Offset

Christof 29-Apr-2007

after IntoElem() the GetOffsets()-method has undefined results as long as no element has been found. Bug or feature?

It is as designed. IntoElem makes the current child position the current main position. So if there was no current child position, then there will be no current main position because it will essentially be before what was the first child. In this case GetOffsets will fail (return false). So use the return value of GetOffsets to determine if the offset results are undefined. You can determine if there is no current main position by checking if GetElemIndex() is 0.

At any point in time, the current position of CMarkup incorporates a current parent, main and child position, retrieved with GetParentElemIndex, GetElemIndex and GetChildElemIndex. If any of those are 0 it is referred to as "no" position on that level, i.e. "no main position" or "no child position". GetOffsets only returns the offsets of the current main position if there is one. See Navigating Levels in CMarkup.