Удаление таблицы стилей из файла XML - PullRequest
1 голос
/ 02 марта 2020

Мне нужно удалить строку таблицы стилей из ввода . xml file:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="class.xsl"?>
<class>
    <student>Jack</student>
    <student>Harry</student>
    <student>Rebecca</student>
    <teacher>Mr. Bean</teacher>
</class>

Ожидаемый результат:

<?xml version="1.0" encoding="UTF-8"?>
<class>
    <student>Jack</student>
    <student>Harry</student>
    <student>Rebecca</student>
    <teacher>Mr. Bean</teacher>
</class>

Я думаю, что могу удалить всю строку, когда она начинается с <?xml-stylesheet, но я бы предпочел найти элегантное решение ...

Я загрузил XML в IXMLDocument, но не нашел ни одной функции для удаления строки <?xml-stylesheet type="text/xsl" href="class.xsl"?>:

uses
  XMLDoc,
  XMLIntf;

procedure TForm1.Button1Click(Sender: TObject);
var
  Doc : IXMLDocument;
begin
  Doc := NewXMLDocument();
  Doc.LoadFromFile('.\input.xml');

  ...

  Doc.SaveToFile('.\output.xml');
end;

Ответы [ 2 ]

3 голосов
/ 02 марта 2020

Вы можете использовать функцию ChildNodes.Delete для удаления узлов. В этом примере я использовал Omni XML в качестве поставщика (чтобы избежать инициализации COM):

program SO60488378;

{$APPTYPE CONSOLE}


{$R *.res}

uses
  Xml.XmlDom,
  Xml.omnixmldom,
  XMLDoc,
  XMLIntf,
  System.SysUtils;

var
  XMLinput : String;
  Doc      : IXMLDocument;

begin
  XMLinput := '<?xml version="1.0" encoding="UTF-8"?>'+#13#10+
            '<?xml-stylesheet type="text/xsl" href="class.xsl"?>'+#13#10+
            '<class>'+#13#10+
            '    <student>Jack</student>'+#13#10+
            '    <student>Harry</student>'+#13#10+
            '     <student>Rebecca</student>'+#13#10+
            '    <teacher>Mr. Bean</teacher>'+#13#10+
            '</class>'+#13#10;
  try
   DefaultDOMVendor := sOmniXmlVendor;
   Doc := NewXMLDocument();
   Doc.LoadFromXML(XMLInput);
   // delete second node from root
   Doc.ChildNodes.Delete(1);
   Writeln(FormatXMLData(Doc.XML.Text));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
 Readln;
end.

Вывод:

<?xml version="1.0"?>
<class>
  <student>Jack</student>
  <student>Harry</student>
  <student>Rebecca</student>
  <teacher>Mr. Bean</teacher>
</class>

Редактировать: Добавление решения как предложено @PeterWolf:

   Doc.LoadFromXML(XMLInput);
   // loop all root nodes and delete first xml-stylesheet node
   // if you want to delete ALL stylesheet nodes, just inverse the loop and remove the break statement
   for Index := 0 to Doc.ChildNodes.Count-1 do
    begin
     Node := Doc.ChildNodes[Index];
     if (Node.NodeType = ntProcessingInstr) and (Node.NodeName = 'xml-stylesheet') then
      begin
       Doc.ChildNodes.Delete(Index);
       Break;
      end;
    end;
   Writeln(FormatXMLData(Doc.XML.Text));
0 голосов
/ 03 марта 2020

RegEx на помощь.

procedure TForm1.btnDoItClick(Sender: TObject);
var sXML : String;
begin
  // Uses System.RegularExpressions;
  sXML := memoXML.Text; // or load it from file
  sXML := Tregex.Replace(sXML, '[\n*](?=<\?xml-stylesheet)(.*)\?>', '');
  memoXML.Text := sXML; // or save it to file
end;
...