我看到有些问题询问如何解析具有相同名称但没有显示迭代方式的标记的XML。 我正在提取格式化的XML
<Documents>
<a:Document>
<a:ID>264</a:ID>
<a:DocumentTitle>Packaged Air-Handling Units</a:DocumentTitle>
</a:Document>
<a:Document>
<a:ID>324</a:ID>
<a:DocumentTitle>Heater Coil</a:DocumentTitle>
</a:document>
</Documents>
我必须解析的代码是
Procedure EpicParse( ED : TDOMDocument30; Var ET : EpicTag );
Var
epicNodeList : IXMLDOMNodelist;
I : Integer;
Begin
epicNodeList := ED.DefaultInterface.getElementsByTagName( 'a:ID' );
ET.id := epicNodeList.item[ 0 ].text;
end;
这将获得a:ID的第一个实例,但是如何设置for循环从a的一个实例获取信息:然后递增并从下一个获取信息。
答案 0 :(得分:0)
首先获取Document元素列表:
myList := ED.DefaultInterface.getElementsByTagName( 'a:Document' );
然后遍历此列表元素,以收集ID元素。
答案 1 :(得分:0)
有几种方法可以做你所问的。以下是其中几个示例,它是一个按钮单击事件处理程序,用于填充普通旧TMemo
的内容。它使用MSXML,因此它仅适用于Windows。我已经对代码进行了评论,以解释它的作用和原因。
我根据您提供的内容(有点)包含了示例XML,因为您发布的内容无效。 (它包含一个名称空间别名a:
,用于未包含的名称空间。此外,XML区分大小写,因此</document>
不是<Document>
的结束元素,因此XML不会正确解析。)在适应实际代码后,您需要在适当的位置添加命名空间别名。
uses
msxml;
const
sXML = '<Documents>'#13 +
' <Document>'#13 +
' <ID>264</ID>'#13 +
' <DocumentTitle>Packaged Air-Handling Units</DocumentTitle>'#13 +
' </Document>'#13 +
' <Document>'#13 +
' <ID>324</ID>'#13 +
' <DocumentTitle>Heater Coil</DocumentTitle>'#13 +
' </Document>'#13 +
'</Documents>'#13 ;
procedure TForm1.Button1Click(Sender: TObject);
var
XMLDoc: IXMLDOMDocument;
NodeList: IXMLDOMNodeList;
Node, SubNode: IXMLDOMNode;
i, j: Integer;
begin
Memo1.Lines.Clear;
XMLDoc := CoDOMDocument.Create;
XMLDoc.loadXML(sXML);
Memo1.Lines.Add('XPath select');
Memo1.Lines.Add('============');
// Select all of the Document elements (and their child nodes)
NodeList := XMLDoc.selectNodes('/Documents/Document');
for i := 0 to NodeList.length - 1 do
begin
// Get each Document node
Node := NodeList.item[i];
// Select the ID node
SubNode := Node.selectSingleNode('ID');
Memo1.Lines.Add('ID: ' + SubNode.firstChild.Text);
// Select the DocumentTitle node
SubNode := Node.selectSingleNode('DocumentTitle');
Memo1.Lines.Add('DocumentTitle: ' + SubNode.firstChild.Text);
Memo1.Lines.Add('');
end;
Memo1.Lines.Add('Iteration');
Memo1.Lines.Add('=========');
// Still select all Document elements using XPath, slightly different expression.
// Note we really didn't need to do this, because the reference we had
// before is still valid. Just included as an example.
NodeList := XMLDoc.selectNodes('//Document');
for i := 0 to NodeList.length - 1 do
begin
// Get each Document node
Node := NodeList.item[i];
// Iterate through it's child nodes (ID and DocumentTitle),
// outputting both the node name and its text content
for j := 0 to Node.childNodes.length - 1 do
begin
SubNode := Node.childNodes[j];
Memo1.Lines.Add(SubNode.nodeName + ': ' + SubNode.firstChild.text);
end;
Memo1.Lines.Add('');
end;
end;