读取XML时出现I / O错误

时间:2015-06-29 10:01:32

标签: xml delphi delphi-6

我正在读取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>

1 个答案:

答案 0 :(得分:3)

那么,您还希望获得此类数据和此类请求的其他内容吗?

请求&#34; // Gordijn [1] / Kamerkant [1] / node()&#34;你真的要求&#34;所有节点都使用Kamerkant [1]&#34;

但是你的Kamerkant是一个空节点 - 它里面包含ZERO节点。 因此,您的请求的结果 - 从缺少内部节点的容器中提取节点 - 只能是NULL或空集,其中没有任何内容。那些不存在的对象是什么nodeValue什么都没有?尝试从无中生有的东西是错误的,你不觉得吗?

只需使用我提到的其中一个XPath计算器,输入您的XML示例并对请求运行评估

  • // Gordijn [1] / Kamerkant [1] /节点()
  • // Gordijn [1] / Kamerkant [1]
  • // Gordijn [1] /节点()

自己看看差异。

也就是说,当你使用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的是错误条件。后者为您提供了一组行,这些行可能是空的,也可能是多个也可以是单数,因此您可以灵活地为这些情况编码。对于意外的输入数据,前者是简洁但脆弱的。后者更灵活,但也更乏味和冗长。绝对是您的选择。但是从你的混乱中判断出我的错误 - 你原来选择使用硬编码的奇异选择可能是不吉利的。