![]() |
|
|
#1
|
||||
|
||||
|
Приветствую, в XML не силен, нужно спарсить данные с файла сигнатур, набросал код с использование компонента SimpleXML, но выдает не все данные и с множеством пустых строк:
Код:
procedure TForm1.Button3Click(Sender: TObject);
var
aDoc: IXmlDocument;
anElem2: IXmlNode;
rez: array of string;
i: integer;
procedure PrintNode(Node: IXmlNode);
var
str: string;
j: word;
NodeList: IXmlNodeList;
begin
Memo2.Lines.Add(trim(Node.GetAttr('name')));
Memo2.Lines.Add(trim(Node.GetChildText('ext')));
NodeList := Node.ChildNodes;
if NodeList.Count > 0 then
for j := 0 to NodeList.Count - 1 do
PrintNode(NodeList.Item[j]);
end;
begin
// Создаем пустой документ XML
aDoc := CreateXmlDocument;
// Считываем из файла
aDoc.Load(ExtractFilePath(ParamStr(0)) + '\mime-types.xml');
PrintNode(aDoc);
end;Код HTML:
|
|
#2
|
|||
|
|||
|
Вот через стандатрный TXMLDocument:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
doc : IXmlDocument;
rootNode : IXMLNode;
I,J : Integer;
begin
Memo1.Lines.Clear;
doc := TXMLDocument.Create(Nil);
Try
doc.LoadFromFile('c:\work\xml.xml');
doc.Active := True;
rootNode := doc.ChildNodes.FindNode('mime-types');
for I := 0 To rootNode.ChildNodes.Count-1 Do
If rootNode.ChildNodes[i].NodeName = 'mime-type' Then
Begin
Memo1.Lines.Add(rootNode.ChildNodes[i].Attributes['name']);
For J := 0 To rootNode.ChildNodes[i].ChildNodes.Count-1 Do
If rootNode.ChildNodes[i].ChildNodes[J].NodeName = 'ext' Then
Memo1.Lines.Add(' ' + rootNode.ChildNodes[i].ChildNodes[J].NodeValue);
End;
Finally
doc := Nil;
End;
end;ЗЫ. Твой xml не правильный. 1. Он не закрыт (ну тут подозреваю, что ты просто скопировал только кусок. 2. Символ '<' недопустим внутри значения. Заменить на '<' 3. Ну и тире убрать перед тегами mime-type (как я понял, это ты просто отметил типа корневые). Последний раз редактировалось lmikle, 07.04.2019 в 19:01. |
|
#3
|
||||
|
||||
|
Да, ты все правильно понял, насчет кода, проверю, отпишусь, пока накидал собственный парсер
|
|
#4
|
|||
|
|||
|
Дык эта, я ж на твоем примере и проверил.
Всего вывел 5 строк. |
|
#5
|
||||
|
||||
|
Вот такие заморочки там встречаются, пытаюсь победить "offset", "type", "value":
Код HTML:
Код:
procedure TForm1.Button4Click(Sender: TObject);
var
doc: IXmlDocument;
rootNode: IXMLNode;
I, J: Integer;
S: string;
begin
Memo1.Lines.Clear;
doc := TXMLDocument.Create(nil);
try
doc.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mime-types.xml');
doc.Active := True;
doc.ChildNodes.FindNode('mime-types');
rootNode := doc.ChildNodes.FindNode('mime-types');
if rootNode.ChildNodes.Count = 0 then
EXIT;
for I := 0 to rootNode.ChildNodes.Count - 1 do
begin
if rootNode.ChildNodes[i].NodeName = 'mime-type' then
begin
Memo2.Lines.Add(rootNode.ChildNodes[i].Attributes['name']);
if rootNode.ChildNodes[i].HasAttribute('description') then//added
Memo2.Lines.Add(rootNode.ChildNodes[i].Attributes['description']);//added
for J := 0 to rootNode.ChildNodes[i].ChildNodes.Count - 1 do
begin
if rootNode.ChildNodes[i].ChildNodes[J].NodeName = 'ext' then
Memo2.Lines.Add(' ' + rootNode.ChildNodes[i].ChildNodes[J].NodeValue);
//
//added, not worked
if rootNode.ChildNodes[i].ChildNodes[J].NodeName = 'magic' then
begin
if rootNode.ChildNodes[i].HasAttribute('offset') then
s := rootNode.ChildNodes[i].Attributes['offset'];
if rootNode.ChildNodes[i].HasAttribute('type') then
s := S + '/' + rootNode.ChildNodes[i].Attributes['type'];
if rootNode.ChildNodes[i].HasAttribute('value') then
s := S + '/' + rootNode.ChildNodes[i].Attributes['value'];
Memo2.Lines.Add(s);
end;
//
end;
Memo2.Lines.Add('------------------------------------');
end;
end;
finally
doc := nil;
end;
end; |
|
#6
|
|||
|
|||
|
Угу, не работает. Потому что у не того тега смотришь
![]() Нужно: Код:
...
if rootNode.ChildNodes[i].ChildNodes[J].HasAttribute('offset') then
s := rootNode.ChildNodes[i].ChildNodes[J].Attributes['offset'];
... |
|
#7
|
||||
|
||||
|
Спасибо, выручил
Код:
procedure TForm1.Button4Click(Sender: TObject);
var
doc: IXmlDocument;
rootNode: IXMLNode;
i, J: integer;
s: string;
begin
Memo2.Lines.Clear;
doc := TXMLDocument.Create(nil);
try
doc.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mime-types.xml');
doc.Active := true;
doc.ChildNodes.FindNode('mime-types');
rootNode := doc.ChildNodes.FindNode('mime-types');
if rootNode.ChildNodes.Count = 0 then
EXIT;
for i := 0 to rootNode.ChildNodes.Count - 1 do
begin
if rootNode.ChildNodes[i].NodeName = 'mime-type' then
begin
Memo2.Lines.add(rootNode.ChildNodes[i].Attributes['name']);
if rootNode.ChildNodes[i].HasAttribute('description') then
Memo2.Lines.add(rootNode.ChildNodes[i].Attributes['description']);
for J := 0 to rootNode.ChildNodes[i].ChildNodes.Count - 1 do
begin
if rootNode.ChildNodes[i].ChildNodes[J].NodeName = 'ext' then
Memo2.Lines.add(' ' + rootNode.ChildNodes[i].ChildNodes[J]
.NodeValue);
//
if rootNode.ChildNodes[i].ChildNodes[J].NodeName = 'magic' then
begin
s := '';
if rootNode.ChildNodes[i].ChildNodes[J].HasAttribute('offset') then
s := rootNode.ChildNodes[i].ChildNodes[J].Attributes['offset'];
if rootNode.ChildNodes[i].ChildNodes[J].HasAttribute('type') then
s := s + '/' + rootNode.ChildNodes[i].ChildNodes[J].Attributes['type'];
if rootNode.ChildNodes[i].ChildNodes[J].HasAttribute('value') then
s := s + '/' + rootNode.ChildNodes[i].ChildNodes[J].Attributes['value'];
Memo2.Lines.add(s);
end;
//
end;
Memo2.Lines.add('------------------------------------');
end;
end;
finally
doc := nil;
end;
end; |
|
#8
|
|||
|
|||
|
Вообще, если xml большой, то рекомендую сделать временную переменную, что бы на каждой итерации не "разрешать" колбасу вида
rootNode.ChildNodes[i].ChildNodes[J] Быстрее работать будет. Но это для реально больших файлов. Ну а для очень больших уже придется искать SAX парсер. Там по другому надо код строить немного. |
|
#9
|
||||
|
||||
|
ок, принял, спасибо
|