Устранить объявление файла XML - PullRequest
1 голос
/ 19 сентября 2019

Я создаю XML-файл в Delphi 7. Я хочу удалить объявление родительского узла из кода.

Это мой код:

var
  XML : IXMLDOCUMENT;
  RootNode, CurNode : IXMLNODE;
begin
  XML := NewXMLDocument;
  XML.Encoding := 'utf-8';
  XML.Options := [doNodeAutoIndent]; // looks better in Editor ;)
  RootNode := XML.AddChild('p:test');
  RootNode.Attributes['xmlns:ds'] := 'Attributes1';
  RootNode.Attributes['xmlns:p'] := 'Attributes2';
  RootNode.Attributes['versione'] := 'FPR12';

  CurNode := RootNode.AddChild('HeadNode');

  CurNode := CurNode.AddChild('SubNode');
  CurNode.Text := 'Test';
  CurNode := CurNode.ParentNode;

  CurNode := CurNode.AddChild('Codice');
  CurNode.Text := '01234567890';
  CurNode := CurNode.ParentNode;

  CurNode := CurNode.ParentNode;

  s := 'C:\Users\web\Desktop\file.xml';
  XMl.SaveToFile(s);
end;

Этомой результат:

<?xml version="1.0" encoding="utf-8"?>
<p:test xmlns:ds="Attributes1" xmlns:p="Attributes2" versione="FPR12">
  <p:HeadNode>
    <p:SubNode>Test</p:SubNode>
    <p:Codice>01234567890</p:Codice>
  </p:HeadNode>
</p:test>

Это то, что я ожидал получить (обратите внимание на отсутствующий «p:» на HeadNode и его вложенных узлах):

<?xml version="1.0" encoding="utf-8"?>
<p:test xmlns:ds="Attributes1" xmlns:p="Attributes2" versione="FPR12">
  <HeadNode>
    <SubNode>Test</SubNode>
    <Codice>01234567890</Codice>
  </HeadNode>
</p:test>

Как я могу получить это?

Ответы [ 2 ]

3 голосов
/ 19 сентября 2019

Это нормальное поведение, любой узел, созданный под родительским узлом, будет нести пространство имен родительского узла.Поскольку вы хотите, чтобы узел HeadNode не содержал пространство имен, вы должны назначить пустое пространство имен при создании этого узла.Если вы посмотрите на функцию TXMLNode.AddChild, вы увидите, что существует функция перегрузки, которая принимает второй параметр, представляющий NameSpaceUri для этого узла.Таким образом, чтобы исправить ваш XML, все, что вам нужно сделать, это изменить строку CurNode := RootNode.AddChild('HeadNode'); на CurNode := RootNode.AddChild('HeadNode', '');

Скомпилируемый пример:

program SO58008911;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  ActiveX,
  XMLIntf,
  XMLDoc,
  System.SysUtils;

procedure TestXML;
var
  XML : IXMLDOCUMENT;
  RootNode, CurNode : IXMLNODE;
begin
  XML := NewXMLDocument;
  XML.Encoding := 'utf-8';
  XML.Options := [doNodeAutoIndent]; // looks better in Editor ;)
  RootNode := XML.AddChild('p:test');
  RootNode.Attributes['xmlns:ds'] := 'Attributes1';
  RootNode.Attributes['xmlns:p'] := 'Attributes2';
  RootNode.Attributes['versione'] := 'FPR12';
  CurNode := RootNode.AddChild('HeadNode', '');
  CurNode := CurNode.AddChild('SubNode');
  CurNode.Text := 'Test';
  CurNode := CurNode.ParentNode;
  CurNode := CurNode.AddChild('Codice');
  CurNode.Text := '01234567890';
  Writeln(XML.XML.Text);
end;

begin
  try
   CoInitialize(nil);
   try
    TestXML;
   finally
    CoUninitialize;
   end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
 Readln;
end.

Вывод:

<?xml version="1.0"?>
<p:test xmlns:ds="Attributes1" xmlns:p="Attributes2" versione="FPR12">
  <HeadNode>
    <SubNode>Test</SubNode>
    <Codice>01234567890</Codice>
  </HeadNode>
</p:test>
0 голосов
/ 19 сентября 2019

Недостаточно просто добавить атрибут xmlns к узлу XML с помощью его свойства Attributes[], вам нужно объявить пространство имен в дереве DOM.IXMLNode имеет метод DeclareNamespace() для этой цели.При создании дочернего узла он наследует пространство имен своего родительского узла, но не в том случае, если вы не объявляете пространство имен правильно для начала.

Кроме того, поскольку ваш корневой test узел имеет 2 пространства имен, объявленных вдля этого вам нужно указать, к какому пространству имен дочернему элементу HeadNode действительно принадлежит.Если вы этого не сделаете, он наследует тот же префикс, что и родительский узел, поэтому он может указывать, в каком пространстве имен он находится, и именно это вы видите.

Попробуйте вместо этого:

var
  XML : IXMLDocument;
  RootNode, CurNode : IXMLNode;
begin
  XML := NewXMLDocument;
  XML.Encoding := 'utf-8';
  XML.Options := [doNodeAutoIndent]; // looks better in Editor ;)

  RootNode := XML.AddChild('p:test');
  RootNode.DeclareNamespace('ds', 'Attributes1');
  RootNode.DeclareNamespace('p', 'Attributes2');
  RootNode.Attributes['versione'] := 'FPR12';

  CurNode := RootNode.AddChild('HeadNode', 'Attributes2');

  CurNode := CurNode.AddChild('SubNode');
  CurNode.Text := 'Test';
  CurNode := CurNode.ParentNode;

  CurNode := CurNode.AddChild('Codice');
  CurNode.Text := '01234567890';
  CurNode := CurNode.ParentNode;

  CurNode := CurNode.ParentNode;

  s := 'C:\Users\web\Desktop\file.xml';
  XML.SaveToFile(s);
end;
<?xml version="1.0"?>
<p:test xmlns:ds="Attributes1" xmlns:p="Attributes2" versione="True">
  <HeadNode xmlns="Attributes2">
    <SubNode>Test</SubNode>
    <Codice>01234567890</Codice>
  </HeadNode>
</p:test>
...