Difference between revisions of "xmlconf/ru"

From Lazarus wiki
Jump to navigationJump to search
(Deleted English categories.)
 
(17 intermediate revisions by one other user not shown)
Line 6: Line 6:
 
Эта документация не является официальной, она основана на обычном процессе 1) изучения исходного кода; 2) экспериментирования; 3) размышлений: «Интересно, это ли имел в виду автор?»
 
Эта документация не является официальной, она основана на обычном процессе 1) изучения исходного кода; 2) экспериментирования; 3) размышлений: «Интересно, это ли имел в виду автор?»
  
==Configuration==
+
==Свойства и процедуры==
=====property Filename: String (published)=====
+
=====property Filename=====
The file name of the xml file.  Setting the filename to a different name:
+
<syntaxhighlight lang="pascal">property Filename: String (published)</syntaxhighlight>
* Flushes the current xml file.
 
* Frees the xmldocument object
 
* If ''Filename'' exists and ''StartEmpty'' is false:
 
** A new xmldocument is created by reading the file, which must have the same root element as ''RootName'' otherwise an exception is raised.
 
** Otherwise, a new xmldocument object is created with root element ''RootName''
 
  
'' I have not checked this by experiment, but it appears that an empty xmldocument is created (in memory) when the component is created, and this can be modified. However, it cannot be saved until it has a file name - there is no default file name - hence all modifications will inevitably be lost when the file name is set.''  
+
Имя XML-файла. Установка другого имени файла:
 +
* Очищает текущий xml-файл.
 +
* Освобождает объект xmldocument
 +
* Если ''Filename'' существует и ''StartEmpty'' имеет значение false:
 +
** Новый xmldocument создается путем чтения файла, который должен иметь тот же root элемент, что и ''RootName'', в противном случае возникает исключение.
 +
** В противном случае создается новый объект xmldocument с корневым элементом ''RootName''
 +
 
 +
''Я не проверял это экспериментально, но похоже, что пустой xmldocument создается (в памяти) при создании компонента, и это можно изменить. Однако его нельзя сохранить, пока у него не будет имени файла - нет имени файла по умолчанию - следовательно, все изменения неизбежно будут потеряны, когда имя файла будет установлено''.
 
   
 
   
=====property StartEmpty: Boolean (published)=====
+
=====property StartEmpty=====
Controls whether an existing xmlfile is read from ''Filename''.
+
<syntaxhighlight lang="pascal">property StartEmpty: Boolean (published)</syntaxhighlight>
* Default is false - an existing file is read.
+
 
 +
Определяет, читается ли существующий xmlfile из ''Filename''.
 +
* По умолчанию false - читается существующий файл.
 
   
 
   
=====property RootName: DOMString (published)=====
+
=====property RootName=====
The name of the root element in the file. Must match the value in the file when an existing file is read.
+
<syntaxhighlight lang="pascal">property RootName: DOMString (published)</syntaxhighlight>
* Default is 'CONFIG'. ''It is simplest to leave this alone unless you have a good reason to change it.''
+
 
 +
Имя root элемента в файле. Должно соответствовать значению в файле при чтении существующего файла.
 +
* По умолчанию - 'CONFIG'. ''Проще всего оставить это в покое, если у вас нет веской причины это менять''.
 +
 
 +
=====procedure Flush=====
 +
<syntaxhighlight lang="pascal">procedure Flush (public)</syntaxhighlight>
  
=====procedure Flush (public)=====
+
Записывает файл xml - если задано имя файла.
Writes the xml file - as long as there is a file name set.
 
  
=====procedure Clear (public)=====
+
=====procedure Clear=====
Recreates the xmldocument as an empty document.
+
<syntaxhighlight lang="pascal">procedure Clear (public)</syntaxhighlight>
  
=====constructor Create(AOwner: TComponent) (public)=====
+
Воссоздает xmldocument как пустой документ.
=====destructor Destroy (public)=====
 
  
==Working with keys and paths==
+
=====constructor Create =====
XMLConfig maintains a "stack" of paths (as an array of widestrings).  The overall path to an element might be
+
<syntaxhighlight lang="pascal">constructor Create(AOwner: TComponent) (public)</syntaxhighlight>
  <rootName>/key1/key2/key3/key4/value="some_value". 
 
This would appear in the file
 
  <CONFIG><key1><key2><key3><key4 value="some_value"/></key3></key2></key1></CONFIG
 
(neglecting any other elements).  However, the path stack can contain paths, not just nodes, so it could be four elements deep as key1;key2; key3;key4, but just as well only two elements as key1/key2;key3/key4, or three elements as key1;key2/key3;key4.
 
  
Further, when reading or setting a value, a complete path can then be specified, so the path "stack" can be completely ignored and the full path (past ''RootName'') specified for each value.  Each value has an effective path, and the path stack is just a convenient way of getting to a specific effective path.
+
=====destructor Destroy=====
 +
<syntaxhighlight lang="pascal">destructor Destroy (public)</syntaxhighlight>
  
=====procedure OpenKey(const aPath: WideString) (public)=====
+
==Работа с ключами и путями==
"Pushes" aPath onto the stack. If the effective path was <RootName>/key1, and  aPath = key2/key3, after the call to OpenKey, the effective path is <RootName>/key1/key2/key3.
+
XMLConfig поддерживает «стек» путей (как массив широких строк). Общий путь к элементу может быть <code><rootName>/key1/key2/key3/key4/value="some_value".</code> 
  
=====procedure CloseKey (public)=====
+
Это будет выглядеть в файле в виде
"Pops" the top path off the stack. Note that this is the last entered path, NOT the top element.  Thus after the OpenKey example above followed by a CloseKey call, the stack reverts to <RootName>/key1, not <RootName>/key1/key2
+
<syntaxhighlight lang="xml">
 +
<CONFIG>
 +
  <key1>
 +
    <key2>
 +
      <key3>
 +
        <key4 value="some_value"/>
 +
      </key3>
 +
    </key2>
 +
  </key1>
 +
</CONFIG></syntaxhighlight>
 +
(пренебрегая любыми другими элементами). Однако стек путей может содержать пути, а не только узлы, поэтому он может состоять как из четырех элементов глубиной <code>key1;key2; key3;key4</code>, так и точно так же только двух элементов <code>key1/key2;key3/key4</code>, или трех элементов <code>key1;key2/key3;key4</code>.
  
=====procedure ResetKey (public)=====
+
Кроме того, при чтении или установке значения можно указать полный путь, так что можно полностью игнорировать «стек» пути и указать полный путь (после ''RootName'') для каждого значения. У каждого значения есть эффективный путь, а стек путей - это просто удобный способ добраться до конкретного эффективного пути.
Completely clears the stack. The effetive path reverts to <RootName>
 
  
==Setting, Getting and Deleting Values==
+
=====procedure OpenKey=====
All values are actually read and written as strings, with other overloaded types providing defined 'AsString' translations.
+
<syntaxhighlight lang="pascal">procedure OpenKey(const aPath: WideString) (public)</syntaxhighlight>
  
=====function  GetValue(const APath: WideString; const ADefault: WideString): WideString (public)<br>procedure SetValue(const APath: WideString; const AValue: WideString) (public)=====
+
"Помещает" aPath в стек. Если текущий путь был <code><RootName>/key1</code> и <code>aPath = key2/key3</code>, после вызова OpenKey текущий путь будет <code><RootName>/key1/key2/key3</code>.
Sets or Gets a string value from ''RootName''/''Effective_path_from_stack''/''APath''.  The path is created if it does not exist on Setting, and ADefault is returned if the path does not exist on Getting.
 
  
=====function GetValue(const APath: WideString; ADefault: Integer): Integer; (public)<br>procedure SetValue(const APath: WideString; AValue: Integer); (public)=====
+
=====procedure CloseKey=====
The integer values are converted to/from strings using IntToStr and strToIntDef
+
<syntaxhighlight lang="pascal">procedure CloseKey (public)</syntaxhighlight>
  
=====function  GetValue(const APath: WideString; ADefault: Boolean): Boolean; (public)<br>procedure SetValue(const APath: WideString; AValue: Boolean); (public)=====
+
"Выталкивает" верхний путь из стека. Обратите внимание, что это последний введенный путь, а НЕ верхний(предыдущий) элемент. Таким образом, после приведенного выше примера OpenKey, за которым следует вызов CloseKey, стек возвращается к <code><RootName>/key1</code>, а не <code><RootName>/key1/key2</code>.
The boolean values are stored as "True" or "False".
 
  
''Warning - some other FCL/LCL XML components (eg those descended from TCustomPropertyStorage, such as TXMLPropStorage) store booleans using integer values, despite using XMLConifg as the storage component.  This is, of course, only a problem if you use the same files from both components, or switch from one to the other during development, as I did.''
+
=====procedure ResetKey=====
 +
<syntaxhighlight lang="pascal">procedure ResetKey (public)</syntaxhighlight>
  
=====procedure SetDeleteValue(const APath: WideString; const AValue, DefValue: WideString); (public)<br>procedure SetDeleteValue(const APath: WideString; AValue, DefValue: Integer); (public)<br>procedure SetDeleteValue(const APath: WideString; AValue, DefValue: Boolean); (public)=====
+
Полностью очищает стек. Эффективный путь возвращается к <code><RootName></code>
  
If AValue = DefValue, the element is deleted.  Otherwise, it is set to AValue.
+
==Получение, установка и удаление значений==
  
''I have not used this, but presumably could be used to store eg values of properties with well defined defaults only when they were different from the defaults.''
+
Все значения фактически читаются и записываются как строки, а другие перегруженные типы предоставляют определенные переводы 'AsString'.
  
=====procedure DeletePath(const APath: WideString); (public)=====
+
=====function  GetValue: WideString / procedure SetValue(const APath: WideString; const AValue: WideString)=====
Deletes '''everything''' beyond path APath
+
<syntaxhighlight lang="pascal">function  GetValue(const APath: WideString; const ADefault: WideString): WideString (public)</syntaxhighlight>
 +
<syntaxhighlight lang="pascal">procedure SetValue(const APath: WideString; const AValue: WideString) (public)</syntaxhighlight>
  
=====procedure DeleteValue(const APath: WideString); (public)=====
+
Устанавливает или получает строковое значение из ''RootName'' / ''Текущий_путь_из_стэка'' / ''APath''. Путь создается, если он не существует в сеттере, и ADefault возвращается, если путь не существует в геттере.
Deletes a '''value''' specified by APath. If APath does not specify a value , it does nothing
+
 
 +
=====function GetValue: Integer / procedure SetValue(const APath: WideString; AValue: Integer)=====
 +
<syntaxhighlight lang="pascal">function GetValue(const APath: WideString; ADefault: Integer): Integer; (public)</syntaxhighlight>
 +
<syntaxhighlight lang="pascal">procedure SetValue(const APath: WideString; AValue: Integer); (public)</syntaxhighlight>
 +
 
 +
Целочисленные значения преобразуются в/из строк с помощью функций <code>IntToStr</code> и <code>strToIntDef</code>.
 +
 
 +
=====function  GetValue: Boolean / procedure SetValue(const APath: WideString; AValue: Boolean)=====
 +
<syntaxhighlight lang="pascal">function  GetValue(const APath: WideString; ADefault: Boolean): Boolean; (public)</syntaxhighlight>
 +
<syntaxhighlight lang="pascal">procedure SetValue(const APath: WideString; AValue: Boolean); (public)</syntaxhighlight>
 +
 
 +
Логические значения сохраняются как "True" или "False".
 +
 
 +
{{Warning|некоторые другие компоненты FCL/LCL XML (например, производные от TCustomPropertyStorage, такие как TXMLPropStorage) хранят логические значения с использованием целочисленных значений, несмотря на использование XMLConifg в качестве компонента хранения. Это, конечно, проблема только в том случае, если вы используете одни и те же файлы из обоих компонентов или переключаетесь с одного на другой во время разработки, как это сделал я}}.
 +
 
 +
=====procedure SetDeleteValue(const APath: WideString; const AValue, DefValue: WideString) / procedure SetDeleteValue(const APath: WideString; AValue, DefValue: Integer) / procedure SetDeleteValue(const APath: WideString; AValue, DefValue: Boolean)=====
 +
 
 +
<syntaxhighlight lang="pascal">procedure SetDeleteValue(const APath: WideString; const AValue, DefValue: WideString); (public)</syntaxhighlight>
 +
<syntaxhighlight lang="pascal">procedure SetDeleteValue(const APath: WideString; AValue, DefValue: Integer); (public)</syntaxhighlight>
 +
<syntaxhighlight lang="pascal">procedure SetDeleteValue(const APath: WideString; AValue, DefValue: Boolean); (public)</syntaxhighlight>
 +
 
 +
Если <code>AValue = DefValue</code>, элемент удаляется. В противном случае устанавливается значение AValue.
 +
 
 +
''Я не использовал это, но предположительно мог бы использовать для хранения, например, значений свойств с четко определенными значениями по умолчанию, только если они отличаются от значений по умолчанию''.
 +
 
 +
=====procedure DeletePath(const APath: WideString)=====
 +
<syntaxhighlight lang="pascal">procedure DeletePath(const APath: WideString); (public)</syntaxhighlight>
 +
 
 +
Удаляет '''все''' за пределами пути APath
 +
 
 +
=====procedure DeleteValue(const APath: WideString)=====
 +
<syntaxhighlight lang="pascal">procedure DeleteValue(const APath: WideString); (public)</syntaxhighlight>
 +
 
 +
Удаляет '''значение''', указанное APath. Если APath не указывает значение, он ничего не делает
 
   
 
   
=====property Modified: Boolean read FModified; (public)=====
+
=====property Modified: Boolean read FModified=====
Allows you to see if the xmldocument has been modified, and hence, needs to be flushed.  ''However, flush does nothing if the document is not modified, so it is easier just to call flush anyway.''
+
<syntaxhighlight lang="pascal">property Modified: Boolean read FModified; (public)</syntaxhighlight>
  
==Example==
+
Позволяет узнать, был ли изменен xmldocument и, следовательно, необходимо ли его очистить.
The following sequence of instructions:
+
 
   XmlConfig1.Filename := FILE_NAME ;        // reads the file if it already exists, but...
+
''Однако процедура <code>Flush</code> ничего не делает, если документ не изменен, поэтому в любом случае проще просто вызвать процедуру <code>Flush</code>''.
   XmlConfig1.Clear ;                        // if the file already exists, clear the data, we want to start from scratch
+
 
   XmlConfig1.SetValue ('L1/L2/L3', '333') ; // add a few data
+
==Пример==
 +
Следующая последовательность инструкций:
 +
<syntaxhighlight lang="pascal">
 +
   XmlConfig1.Filename := FILE_NAME ;        // читаем файл, если он уже существует, но ...
 +
   XmlConfig1.Clear ;                        // если файл уже существует, то очищаем данные, потому что хотим начать с нуля
 +
   XmlConfig1.SetValue ('L1/L2/L3', '333') ; // добавляем немного данных
 
   XmlConfig1.SetValue ('L1/L2/L4', '44') ;
 
   XmlConfig1.SetValue ('L1/L2/L4', '44') ;
   XmlConfig1.SetValue ('L1/L2/L3', '33') ;  // this will overwrite the previous value
+
   XmlConfig1.SetValue ('L1/L2/L3', '33') ;  // это перезапишет предыдущее значение
   XmlConfig1.OpenKey  ('L1/L2') ;          // from now on, all keys will be relative to L1/L2
+
   XmlConfig1.OpenKey  ('L1/L2') ;          // с этого момента все ключи будут относиться к L1/L2
   XmlConfig1.SetValue ('Lm', 'mm') ;        // these will be added in L1/L2
+
   XmlConfig1.SetValue ('Lm', 'mm') ;        // они будут добавлены в L1/L2
 
   XmlConfig1.SetValue ('Lm/Ln', 'nn') ;
 
   XmlConfig1.SetValue ('Lm/Ln', 'nn') ;
   XmlConfig1.SetValue ('/Lx/Ly', 'yy') ;    // but because of the initial "/", this will be added to the root
+
   XmlConfig1.SetValue ('/Lx/Ly', 'yy') ;    // и из-за начального символа '/' оно будет добавлено в root
 
   XmlConfig1.CloseKey ;
 
   XmlConfig1.CloseKey ;
   XmlConfig1.SetValue ('L6/L7', '77') ;    // L6 will be deleted
+
   XmlConfig1.SetValue ('L6/L7', '77') ;    // L6 будет удален
 
   XmlConfig1.SetValue ('L9', '99') ;
 
   XmlConfig1.SetValue ('L9', '99') ;
   XmlConfig1.SetValue ('L9/L99', '9999') ;  // the previous L9 was an attibute, this one will be a node
+
   XmlConfig1.SetValue ('L9/L99', '9999') ;  // Предыдущее L9 было атрибутом, теперь оно будет узлом
 
   XmlConfig1.DeletePath ('L6') ;
 
   XmlConfig1.DeletePath ('L6') ;
 
   XmlConfig1.Flush ;
 
   XmlConfig1.Flush ;
 +
</syntaxhighlight>
  
will give this XML:
+
даст такой XML:
 +
<syntaxhighlight lang="xml">
 
   <?xml version="1.0" encoding="utf-8"?>
 
   <?xml version="1.0" encoding="utf-8"?>
 
   <CONFIG L9="99">
 
   <CONFIG L9="99">
Line 110: Line 163:
 
     <L9 L99="9999"/>
 
     <L9 L99="9999"/>
 
   </CONFIG>
 
   </CONFIG>
 +
</syntaxhighlight>
  
Note that the last item in the aPath parameter for SetValue is actually an attribute: XmlConfig1.SetValue ('L1/L2/L3', '333') actually sets attribute L3 for element L1/L2.
+
Обратите внимание, что последний элемент в параметре aPath для SetValue на самом деле является атрибутом: <code>XmlConfig1.SetValue ('L1/L2/L3', '333')</code> фактически задает атрибут <code>L3</code> для элемента <code>L1/L2</code>.
  
 
----
 
----
  
== See also ==
+
== См.также ==
* XMLConf/TXMLConf is provided by the [[fcl-xml]] package.
+
* XMLConf/TXMLConf представлен в пакете [[fcl-xml]].
 
 
 
 
[[Category:FCL]]
 
[[Category:Packages]]
 
[[Category:XML]]
 

Latest revision as of 18:46, 2 January 2022

English (en) русский (ru)

Модуль XMLConf предоставляет компонент TXMLConfig. Он использует объект TXMLDocument для чтения и записи XML-файла, но происходит непосредственно от TComponent.

Отказ от ответственности

Эта документация не является официальной, она основана на обычном процессе 1) изучения исходного кода; 2) экспериментирования; 3) размышлений: «Интересно, это ли имел в виду автор?»

Свойства и процедуры

property Filename
property Filename: String (published)

Имя XML-файла. Установка другого имени файла:

  • Очищает текущий xml-файл.
  • Освобождает объект xmldocument
  • Если Filename существует и StartEmpty имеет значение false:
    • Новый xmldocument создается путем чтения файла, который должен иметь тот же root элемент, что и RootName, в противном случае возникает исключение.
    • В противном случае создается новый объект xmldocument с корневым элементом RootName

Я не проверял это экспериментально, но похоже, что пустой xmldocument создается (в памяти) при создании компонента, и это можно изменить. Однако его нельзя сохранить, пока у него не будет имени файла - нет имени файла по умолчанию - следовательно, все изменения неизбежно будут потеряны, когда имя файла будет установлено.

property StartEmpty
property StartEmpty: Boolean (published)

Определяет, читается ли существующий xmlfile из Filename.

  • По умолчанию false - читается существующий файл.
property RootName
property RootName: DOMString (published)

Имя root элемента в файле. Должно соответствовать значению в файле при чтении существующего файла.

  • По умолчанию - 'CONFIG'. Проще всего оставить это в покое, если у вас нет веской причины это менять.
procedure Flush
procedure Flush (public)

Записывает файл xml - если задано имя файла.

procedure Clear
procedure Clear (public)

Воссоздает xmldocument как пустой документ.

constructor Create
constructor Create(AOwner: TComponent) (public)
destructor Destroy
destructor Destroy (public)

Работа с ключами и путями

XMLConfig поддерживает «стек» путей (как массив широких строк). Общий путь к элементу может быть <rootName>/key1/key2/key3/key4/value="some_value".

Это будет выглядеть в файле в виде

<CONFIG>
  <key1>
    <key2>
      <key3>
        <key4 value="some_value"/>
      </key3>
    </key2>
  </key1>
</CONFIG>

(пренебрегая любыми другими элементами). Однако стек путей может содержать пути, а не только узлы, поэтому он может состоять как из четырех элементов глубиной key1;key2; key3;key4, так и точно так же только двух элементов key1/key2;key3/key4, или трех элементов key1;key2/key3;key4.

Кроме того, при чтении или установке значения можно указать полный путь, так что можно полностью игнорировать «стек» пути и указать полный путь (после RootName) для каждого значения. У каждого значения есть эффективный путь, а стек путей - это просто удобный способ добраться до конкретного эффективного пути.

procedure OpenKey
procedure OpenKey(const aPath: WideString) (public)

"Помещает" aPath в стек. Если текущий путь был <RootName>/key1 и aPath = key2/key3, после вызова OpenKey текущий путь будет <RootName>/key1/key2/key3.

procedure CloseKey
procedure CloseKey (public)

"Выталкивает" верхний путь из стека. Обратите внимание, что это последний введенный путь, а НЕ верхний(предыдущий) элемент. Таким образом, после приведенного выше примера OpenKey, за которым следует вызов CloseKey, стек возвращается к <RootName>/key1, а не <RootName>/key1/key2.

procedure ResetKey
procedure ResetKey (public)

Полностью очищает стек. Эффективный путь возвращается к <RootName>

Получение, установка и удаление значений

Все значения фактически читаются и записываются как строки, а другие перегруженные типы предоставляют определенные переводы 'AsString'.

function GetValue: WideString / procedure SetValue(const APath: WideString; const AValue: WideString)
function  GetValue(const APath: WideString; const ADefault: WideString): WideString (public)
procedure SetValue(const APath: WideString; const AValue: WideString) (public)

Устанавливает или получает строковое значение из RootName / Текущий_путь_из_стэка / APath. Путь создается, если он не существует в сеттере, и ADefault возвращается, если путь не существует в геттере.

function GetValue: Integer / procedure SetValue(const APath: WideString; AValue: Integer)
function GetValue(const APath: WideString; ADefault: Integer): Integer; (public)
procedure SetValue(const APath: WideString; AValue: Integer); (public)

Целочисленные значения преобразуются в/из строк с помощью функций IntToStr и strToIntDef.

function GetValue: Boolean / procedure SetValue(const APath: WideString; AValue: Boolean)
function  GetValue(const APath: WideString; ADefault: Boolean): Boolean; (public)
procedure SetValue(const APath: WideString; AValue: Boolean); (public)

Логические значения сохраняются как "True" или "False".

Warning-icon.png

Предупреждение: некоторые другие компоненты FCL/LCL XML (например, производные от TCustomPropertyStorage, такие как TXMLPropStorage) хранят логические значения с использованием целочисленных значений, несмотря на использование XMLConifg в качестве компонента хранения. Это, конечно, проблема только в том случае, если вы используете одни и те же файлы из обоих компонентов или переключаетесь с одного на другой во время разработки, как это сделал я

.

procedure SetDeleteValue(const APath: WideString; const AValue, DefValue: WideString) / procedure SetDeleteValue(const APath: WideString; AValue, DefValue: Integer) / procedure SetDeleteValue(const APath: WideString; AValue, DefValue: Boolean)
procedure SetDeleteValue(const APath: WideString; const AValue, DefValue: WideString); (public)
procedure SetDeleteValue(const APath: WideString; AValue, DefValue: Integer); (public)
procedure SetDeleteValue(const APath: WideString; AValue, DefValue: Boolean); (public)

Если AValue = DefValue, элемент удаляется. В противном случае устанавливается значение AValue.

Я не использовал это, но предположительно мог бы использовать для хранения, например, значений свойств с четко определенными значениями по умолчанию, только если они отличаются от значений по умолчанию.

procedure DeletePath(const APath: WideString)
procedure DeletePath(const APath: WideString); (public)

Удаляет все за пределами пути APath

procedure DeleteValue(const APath: WideString)
procedure DeleteValue(const APath: WideString); (public)

Удаляет значение, указанное APath. Если APath не указывает значение, он ничего не делает

property Modified: Boolean read FModified
property Modified: Boolean read FModified; (public)

Позволяет узнать, был ли изменен xmldocument и, следовательно, необходимо ли его очистить.

Однако процедура Flush ничего не делает, если документ не изменен, поэтому в любом случае проще просто вызвать процедуру Flush.

Пример

Следующая последовательность инструкций:

  XmlConfig1.Filename := FILE_NAME ;        // читаем файл, если он уже существует, но ...
  XmlConfig1.Clear ;                        // если файл уже существует, то очищаем данные, потому что хотим начать с нуля
  XmlConfig1.SetValue ('L1/L2/L3', '333') ; // добавляем немного данных
  XmlConfig1.SetValue ('L1/L2/L4', '44') ;
  XmlConfig1.SetValue ('L1/L2/L3', '33') ;  // это перезапишет предыдущее значение
  XmlConfig1.OpenKey  ('L1/L2') ;           // с этого момента все ключи будут относиться к L1/L2
  XmlConfig1.SetValue ('Lm', 'mm') ;        // они будут добавлены в L1/L2
  XmlConfig1.SetValue ('Lm/Ln', 'nn') ;
  XmlConfig1.SetValue ('/Lx/Ly', 'yy') ;    // и из-за начального символа '/' оно будет добавлено в root
  XmlConfig1.CloseKey ;
  XmlConfig1.SetValue ('L6/L7', '77') ;     // L6 будет удален
  XmlConfig1.SetValue ('L9', '99') ;
  XmlConfig1.SetValue ('L9/L99', '9999') ;  // Предыдущее L9 было атрибутом, теперь оно будет узлом
  XmlConfig1.DeletePath ('L6') ;
  XmlConfig1.Flush ;

даст такой XML:

  <?xml version="1.0" encoding="utf-8"?>
  <CONFIG L9="99">
    <L1>
      <L2 L3="33" L4="44" Lm="mm">
        <Lm Ln="nn"/>
      </L2>
    </L1>
    <Lx Ly="yy"/>
    <L9 L99="9999"/>
  </CONFIG>

Обратите внимание, что последний элемент в параметре aPath для SetValue на самом деле является атрибутом: XmlConfig1.SetValue ('L1/L2/L3', '333') фактически задает атрибут L3 для элемента L1/L2.


См.также

  • XMLConf/TXMLConf представлен в пакете fcl-xml.