Odczyt i zapis wartości z istniejącego pliku XML

0

Witam wszystkich, mam taki plik XML

<?xml version="1.0" encoding="UTF-8" ?>
<save>
    <header version="2" time="1534250670" />
    <version major="3" minor="6" revision="0" build="3" />
    <region id="Config">
        <node id="root">
            <children>
                <node id="ConfigEntry">
                    <attribute id="MapKey" value="Language" type="22" />
                    <attribute id="Type" value="1" type="5" />
                    <attribute id="Value" value="English" type="20" />
                </node>
            </children>
        </node>
    </region>
</save>

Zna ktoś jakiś prosty sposób, jak w Delphi dać w stringa (np LanguageLabel) to co jest w value="English"
Po czym "w pliku XML" zmienić value="English" np na Polish ?

Z góry dzieki za podpowiedzi.

0

@abrakadaber: to mi nic nie daje, jakies zawiłe te podpowiedzi.

Tak czy inaczej, użyłem do odczytu TSrringList, chociaz wiem ze to nie jest profesionalne podejscie.

Tak na szybko

unit main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
  
{

XML

<?xml version="1.0" encoding="UTF-8" ?>
<save>
    <header version="2" time="1534250670" />
    <version major="3" minor="6" revision="0" build="3" />
    <region id="Config">
        <node id="root">
            <children>
                <node id="ConfigEntry">
                    <attribute id="MapKey" value="Language" type="22" />
                    <attribute id="Type" value="1" type="5" />
                    <attribute id="Value" value="Polish" type="20" />
                </node>
            </children>
        </node>
    </region>
</save>

}

  const
    LangLine = '<attribute id="Value" value="Polish" type="20" />';
    XMLFILE = 'test.xml';

type
  TMainForm = class(TForm)
  private
    { Private declarations }
    function AddSplash(const s: string): string;
    function GetLanguageXML(const FileName: string = XMLFILE): string;
  public
    { Public declarations }
  end;

  var
  MainForm: TMainForm;

implementation

{$R *.dfm}

// dodaj na koncu \
function TMainForm.AddSplash(const s: string): string;
begin
  if s[Length(s)] <> '\'
  then
    Result := s + '\'
  else
    Result := s;
end;

function TMainForm.GetLanguageXML(const FileName: string): string;
var
  XML: TStringList;
  s: string;
  i, x, y: Integer;
begin
  Result := '';

  XML := TStringList.Create();
  try
    XML.LoadFromFile(AddSplash(ExtractFilePath(Application.ExeName)) + FileName);

    /// szukanie indexu z lina do edycji jezyka
    for i := XML.Count - 1 downto 0 do begin
      if TrimLeft(XML[i]) = LangLine then begin
          s := XML[i];
          Break;
       end;
    end;

    // obecny jezyk w <attribute id="Value" value=TU JEST JEZYK
    x := System.SysUtils.AnsiPos('value', s) + Length('value') + 2;
    y := System.SysUtils.AnsiPos('type', s) - 2;

    Result := Copy(s, x, y-x);
    
  finally
    XML.Free();
  end;
end;

end.
1

@Observer2323: Szalony programista ? Google przestało działać ? Pierwszy wynik https://stackoverflow.com/questions/3687116/xml-sample-app-settings-in-xml#3689440

4

Delphi ma dedykowane narzędzia do obsługi XML'a. Klasa Txmldocument oraz interfejs Ixmldocument.

unit UnitXML;
interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, xmldoc, xmlintf;

type
  TForm2 = class(TForm)
    btnGetNodeValue: TButton;
    btnSetNodeValue: TButton;
    Memo1: TMemo;
    procedure btnGetNodeValueClick(Sender: TObject);
    procedure btnSetNodeValueClick(Sender: TObject);
  end;

var
  Form2: TForm2;

const
  xmlTxt = //
    '<save> ' + //
    '    <header version="2" time="1534250670" /> ' + //
    '    <version major="3" minor="6" revision="0" build="3" /> ' + //
    '    <region id="Config"> ' + //
    '        <node id="root"> ' + //
    '            <children> ' + //
    '                <node id="ConfigEntry"> ' + //
    '                    <attribute id="MapKey" value="Language" type="22" /> ' + //
    '                    <attribute id="Type" value="1" type="5" /> ' + //
    '                    <attribute id="Value" value="English" type="20" /> ' + //
    '                </node> ' + //
    '            </children> ' + //
    '        </node> ' + //
    '    </region> ' + //
    '</save>';

implementation

{$R *.dfm}

function getNodeValue(aXmlTxt: string): string;
var
  lXml: Ixmldocument;
  lNode: Ixmlnode;
begin
  lXml := Txmldocument.create(nil);
  lXml.XML.Text := aXmlTxt;
  lXml.Active := true;
  lNode := lXml.DocumentElement.ChildNodes.FindNode('region');
  lNode := lNode.ChildNodes.FindNode('node');
  lNode := lNode.ChildNodes.FindNode('children');
  lNode := lNode.ChildNodes.FindNode('node');
  result := lNode.ChildNodes[0].Attributes['value'];
end;

function setNodeValue(aXmlTxt, aValue: string): string;
var
  lXml: Ixmldocument;
  lNode: Ixmlnode;
begin
  lXml := Txmldocument.create(nil);
  lXml.Options := lXml.Options + [doNodeAutoindent];
  lXml.XML.Text := aXmlTxt;
  lXml.Active := true;
  lNode := lXml.DocumentElement.ChildNodes.FindNode('region');
  lNode := lNode.ChildNodes.FindNode('node');
  lNode := lNode.ChildNodes.FindNode('children');
  lNode := lNode.ChildNodes.FindNode('node');
  lNode.ChildNodes[0].Attributes['value'] := aValue;
  result := lXml.XML.Text;
end;

procedure TForm2.btnGetNodeValueClick(Sender: TObject);
begin
  self.Memo1.Lines.Text := getNodeValue(xmlTxt);
end;

procedure TForm2.btnSetNodeValueClick(Sender: TObject);
begin
  self.Memo1.Lines.Text := setNodeValue(xmlTxt, 'Polish');
end;

end.
0

@grzegorz_so: wielkie dzięki o to mi właśnie chodziło.

1 użytkowników online, w tym zalogowanych: 0, gości: 1