0

I'm trying to make XML file using NativeXML v4.09 and used it with structure like this :

<?xml version="1.0" encoding="utf-8"?>
<Root>
   <word1 word2>this is value</word1 word2>
</Root>

I write the simple code like this :

procedure TForm1.ButtonWriteClick(Sender: TObject);
var aaa: TNativeXml;
    vSectionName : string;
begin
    vSectionName := 'word1 word2';//Name of Section with two words sparated with space
    aaa:= TNativeXml.Create(Self);
    aaa.CreateName('Root');
    aaa.Root.NodeNew(vSectionName);

    aaa.Root.NodeByName('word1 word2').Value:='this is value';

    aaa.XmlFormat := xfReadable;

    aaa.SaveToFile('test.xml');
end;

And to read node of a Section I write code like this :

procedure TForm1.ButtonReadClick(Sender: TObject);
var aaa : TNativeXml;
    vSectionName : string;
    vNode : TXmlNode;
begin
    vSectionName := 'word1 word2';//Name of Section with two words sparated with space
    try
       aaa := TNativeXml.Create(Self);
       aaa.LoadFromFile('test.xml');
       vNode := aaa.Root.NodeByName(vSectionName);
       if vNode=nil then
          ShowMessage('Section not found')
       else
          ShowMessage('Section found');
    finally
       FreeAndNil(aaa);
    end;
end;

I can create the XML file "test.xml" with structure above that I want to. But when I want read the node section with two words name (like "word1 word2" name) always got message "Section not found" because vNode is always NIL from NodeByName function.

Then to tracking the error I add some code in NativeXML.TXMLNode.NodeByName function like this:

function TXmlNode.NodeByName(const AName: Utf8String): TXmlNode;
var i: integer;
    vF : boolean;
begin
    result := nil;
    for i := 0 to GetNodeCount - 1 do begin
       vF := (Utf8CompareText(GetNodes(i).Name, AName) = 0);
       if vF then
          Application.MessageBox(PWideChar('TXmlNode.NodeByName-> Found AName='+AName+'|GetNodes('+IntToStr(i)+').Name='+GetNodes(i).Name+'|GetNodes('+IntToStr(i)+').NameUnicode='+GetNodes(i).NameUnicode),'TXmlNode.NodeByName',0)
       else
          Application.MessageBox(PWideChar('TXmlNode.NodeByName-> Not Found AName='+AName+'|GetNodes('+IntToStr(i)+').Name='+GetNodes(i).Name+'|GetNodes('+IntToStr(i)+').NameUnicode='+GetNodes(i).NameUnicode),'TXmlNode.NodeByName',0);
       //if (Utf8CompareText(GetNodes(i).Name, AName) = 0) then
       if vF then begin
         Result := GetNodes(i);
         exit;
       end;
    end;
end;

And get this messagebox :

MessageBox display

I see the section name change from two words ("word1 word2" name) to single word ("word1" name).

Is this a bug in section name with multiple words name with space(s) or the section's name just must a single word without space(s) ? If section's name must single word or more and without space(s), why we can create XML with section's name with two or more words with space(s) but we can not get the section node when we read it with NodeByName ?

Haykal HM
  • 31
  • 5

2 Answers2

1

Your document is not valid XML. Tag names must not contain space characters.

XML specification: XML Start-Tags, End-Tags, and Empty-Element Tags

Ondrej Kelle
  • 36,941
  • 2
  • 65
  • 128
  • I suspect from the start that XML elements cannot have spaces but I am currios why we can write XML Doc with section's name contain space. Okay, I think I add some code to fixed it. Thank you to all of you. Case closed. – Haykal HM Apr 19 '16 at 04:55
  • Well we can't since it wouldn't be valid XML; you've just found that out. – Ondrej Kelle Apr 19 '16 at 04:59
1

XML elements cannot have spaces in their names. If the XML library allows spaced names when creating XML documents, then that library is wrong. You should report the bug to the vendor. (The bug report might be dismissed as a usage error, though, since no correct program should be attempting multi-word names in the first place.)

You will need to come up with some other way of representing your data. Perhaps you could store your section names in attribute values, or as element contents.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467