With the latest NativeXml (v4.03 svn), is it possible to get the value of an element with previous and trailing spaces without iteratively checking the type?

As shown below, the last NativeXml (v4.03 svn) sees the value of the element as three parts: the previous space, char data and trailing space. Therefore, it was possible to check the child nodes of the element iteratively to get the value with previous and trailing spaces. However, this is not necessary for legacy NativeXml (v3.10), and so I wonder what is the preferred way (perhaps without such iterative string checking / concatenation) for this?

sample XML document

<?xml version="1.0" encoding="UTF-8" ?>
<CDXML><s>beforeLineBreak
</s></CDXML>

sample XML document

<?xml version="1.0" encoding="UTF-8" ?>
<CDXML><s>
afterLineBreak</s></CDXML>

sample code using NativeXml v3.10 that does not require iterative validation

procedure XXX310;
var
  element: TXmlNode; 
  elementType: TElementType;
begin
  elementType := element.ElementType;
  element.ElementType := xeCharData;
  ... element.ValueAsString ...
  element.ElementType := elementType;      
end;

NativeXml v3.10 related source code (full method body)

function TXmlNode.GetValueAsString: UTF8String;
begin
  if FElementType = xeNormal then
    Result := UnEscapeString(sdUTF8Trim(FValue))
  else
    Result := UnEscapeString(FValue);
end;

NativeXml v4.03 svn,

procedure XXX403;
var
  tempString: String;
  element: TXmlNode; // actually TsdElement
begin
  tempString := '';
  for I := element.DirectNodeCount to element.NodeCount - 1 do
    if element.Nodes[I] is TsdCharData then
       tempString := tempString + (element.Nodes[I] as TsdCharData).Value;

  ... tempString ...
end;

NativeXml v4.03 svn ( )

unit NativeXml;
interface

  // TXmlNode is the ancestor for all nodes in the xml document. See TsdElement
  // for the elements, TsdAttribute for the attributes.
  TXmlNode = class(TDebugPersistent)
  Public
    // The value of the node. For elements this is the element value (based on
    // first chardata fragment), for attributes this is the attribute value. The
    // string is encoded as UTF8. Use ToWide(Node.Value) or Node.ValueUnicode
    // to get a UnicodeString compatible with "unicode" windows methods.
    property Value: Utf8String read GetValue write SetValue;
  end;

  // Node representing an xml element.
  TsdElement = class(TsdContainerNode)
  protected
    // parses the value in descendants TsdElement and TsdDocType
    procedure ParseIntermediateData(P: TsdXmlParser); override;
  end;

implementation

function TsdElement.GetValue: Utf8String;
begin
  // Return the value of the CharData subnode designated by the parser
  if (FValueIndex >= 0) and (FValueIndex < FNodes.Count) then
  begin
    // chardata value at FValueIndex
    // This calls TsdCharData.GetValue(),
    // then TsdCharData.GetCoreValue().
    Result := FNodes[FValueIndex].Value;

    // do un-normalisation if mac/windows
    if GetEolStyle <> esLF then
      Result := sdUnNormaliseEol(Result, GetEolStyle);

  end else
    // default value
    Result := '';
end;

procedure TsdElement.ParseIntermediateData(P: TsdXmlParser);  
begin  
  CharDataString := sdTrim(S, PreString, PostString);

  if GetPreserveWhiteSpace and (Length(PreString) > 0) then
  begin
    WhiteSpaceNode := TsdWhiteSpace.Create(TNativeXml(FOwner));
  end;

  if length(CharDataString) > 0 then
  begin
    // Insert CharData node
    CharDataNode := TsdCharData.Create(TNativeXml(FOwner));
  end;  

  if GetPreserveWhiteSpace and (Length(PostString) > 0) then
  begin
    WhiteSpaceNode := TsdWhiteSpace.Create(TNativeXml(FOwner));
  end;
end;

end.  
+5

All Articles