|
#1
|
||||
|
||||
Парсинг XML
Приветствую, в 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
|
||||
|
||||
ок, принял, спасибо
|