我正在读取XML文件并在读取节点时出现i / o错误
<kamerkant/>
。我使用以下语句来读取节点:
Lclvalue := Sel.Selectnode('//Gordijn[1]/Kamerkant[1]/node()').nodeValue
XML
<Gordijn>
<StofNaam>Aroma 211004</StofNaam>
<Kleur>211</Kleur>
<Gordijnsoort>streepgordijn</Gordijnsoort>
<Vertrek>Woonkamer voor</Vertrek>
<Kamerkant/>
<Hoogte>100.0</Hoogte>
</Gordijn>
答案 0 :(得分:3)
那么,您还希望获得此类数据和此类请求的其他内容吗?
请求&#34; // Gordijn [1] / Kamerkant [1] / node()&#34;你真的要求&#34;所有节点都使用Kamerkant [1]&#34;
但是你的Kamerkant
是一个空节点 - 它里面包含ZERO节点。
因此,您的请求的结果 - 从缺少内部节点的容器中提取节点 - 只能是NULL或空集,其中没有任何内容。那些不存在的对象是什么nodeValue
什么都没有?尝试从无中生有的东西是错误的,你不觉得吗?
只需使用我提到的其中一个XPath计算器,输入您的XML示例并对请求运行评估
自己看看差异。
也就是说,当你使用SQL时 - 你必须在一些通用的非Delphi SQL工具中调试你的查询和数据,并且只有在你得到正确的测试SQL请求后才能将它复制到你的Delphi代码中。 /> 同样适用于XPath - 您最好首先使用XPath计算器来调试Delphi之外的XPath请求,并且只有在成功时才将经过测试的正确XPath重新放入Delphi代码中。
根据
你可能(取决于你的各种源数据)可以使用像
这样的东西 Lclvalue := Sel.Selectnode('//Gordijn[1]/Kamerkant[1]');
if LclValue.hasChildNodes then begin
LclNodes := LclValue.childNodes;
for i := 1 to LclNodes.length do begin
LclValue := LclNodes.item[i];
... process LclValue....
end;
end;
LclValue := nil; // release memory you need no more
LclNodes := nil;
那就是说,不要认为这是真正最有效的方法,它显然不适合基于集合的XPath世界观。对我来说,它似乎是索引顺序访问方法&#34;应用于SQL数据源。
所以对我来说,看起来你不必特别选择一个节点,少于第一个节点(那些&#34; [1]&#34;在你的查询中 - 为什么???)。
你真的试图获得可能对你感兴趣的所有节点的列表,并为没有的事件做好准备。
例如,你得到的I / O错误 - 它可能(或者可能不是,我不知道,检查文档)正是你的xml解析器的方式告诉&#34;没有找到,空结果和# 34 ;.
我打开www.google.com并在那里输入&#34; stackoverflow xpath检查节点是否为空&#34;
也就是说,有不同的XPath版本和不同的XPath引擎 - 所以代码的XML解析器是否只能使用这些方法,你可以确定。
但至少以下 - 也不是非常有效 - 似乎是可能的;
LclNodes := Sel.Selectnodes('//Gordijn/Kamerkant'); // all the Kamerkants
// MAYBE check for error if XML source has no single Kamerkant,
// i can only GUESS how that maybe would be represented
// you can CHECK it or READ DOCS
for i := 1 to LclNodes.length do begin
// i GUESS LclNodes.length=0 for no Kamerkants data input - i may be badly wrong
LclValue := LclNodes.item[i]; // some Kamerkant
if LclValue.hasChildNodes then begin
LclKamerkantNodes := LclValue.childNodes;
for j := 1 to LclKamerkantNodes.length do begin
LclValue := LclKamerkantNodes.item[j];
... process LclValue....
end;
end;
end;
LclValue := nil; // release memory you need no more
LclKamerkantNodes := nil;
LclNodes := nil;
在后面的代码中我假设一般来说,XPath对SelctNode / SelectNodes的态度与SQL对单一/一般SELECT操作的态度相同。前者需要产生恰好1行的结果,少于1或多于1的是错误条件。后者为您提供了一组行,这些行可能是空的,也可能是多个也可以是单数,因此您可以灵活地为这些情况编码。对于意外的输入数据,前者是简洁但脆弱的。后者更灵活,但也更乏味和冗长。绝对是您的选择。但是从你的混乱中判断出我的错误 - 你原来选择使用硬编码的奇异选择可能是不吉利的。