为什么';t IXMLNode.IsTextElement是否为CDATA元素返回True?

为什么';t IXMLNode.IsTextElement是否为CDATA元素返回True?,xml,delphi,delphi-2007,Xml,Delphi,Delphi 2007,我们正在使用Delphi2007和oxmldomOpenXML提供程序 正常情况下的输入文件如下所示: <root> <child>Some Text</child> </root> Node.IsTextElement突然返回False,但Node.Text仍按预期工作 我知道IXMLNode.IsTextElement只是一种方便的方法,但我觉得这种行为相当奇怪 作为一种解决方法,我们现在使用以下自定义方法: class function

我们正在使用Delphi2007和
oxmldom
OpenXML
提供程序

正常情况下的输入文件如下所示:

<root>
  <child>Some Text</child>
</root>
Node.IsTextElement
突然返回
False
,但
Node.Text
仍按预期工作

我知道
IXMLNode.IsTextElement
只是一种方便的方法,但我觉得这种行为相当奇怪

作为一种解决方法,我们现在使用以下自定义方法:

class function TXmlUtils.IsTextOrCDataElement(ANode: IXMLNode): Boolean;
begin
  Result := False;
  if ANode.ChildNodes.Count = 0 then begin
    if ANode.NodeType in [ntText, ntCData] then begin
      Result := True;
    end;
  end else
  if ANode.ChildNodes.Count = 1 then begin
    if ANode.ChildNodes.First.NodeType in [ntText, ntCData] then begin
      Result := True;
    end;
  end;
end;

我的问题是:为什么
IsTextElement
不能与
CDATA
节点一起工作,并且有更简单的解决方法吗?

正如Ritsaert Hornstra在评论中所写,CDATA不是DOM树的文本节点。这是CDATA节点

文本属性是不同的。例如,当当前节点是一个属性时,文本可能会返回该属性的值


如果要检查当前节点是CDATA节点还是文本节点,只需使用Delphi
is
操作符即可。还有一种类似于
nodeType
的属性,您正在使用它:-)

对于Cdata节点,它不会返回true,因为它不是这样编写的。这是不幸的,因为XML数据的使用者通常不应该关心文本在序列化数据中的表示方式。您的选择很好。

如果要检查当前节点是CDATA节点还是文本节点,只需使用Delphi
is
操作符即可。还有一个类似于
nodeType
属性的东西,您正在使用它:-)


但是CDATA元素不是文本元素,因此这种行为是正确的。您的变通方法似乎根本不是一种变通方法,而是一种实现您期望的正确行为。@RitsaertHornstra:您应该将其作为一个答案发布,以获得信任。因此,
Text
属性适用于不同类型的节点,
IsTextElement
只查找“Text”类型的节点?对吗?但是@Ritsaert,IsTextElement方法对于非文本节点也返回True。具体来说,对于具有单个文本节点子级的元素,例如上面示例中的
,它返回True。因此,由于它已经不同于简单的
is
支持的
测试,Jens提出的为什么它对其他文本类节点不返回True的问题是合理的。@Rob Kennedy-在
IsTextElement
中有
元素
word。并且是
元素
,它包含
文本
节点。从字面上说,对我来说,这个函数一切都很好。+1因为你的答案在技术上是正确的,但实际上我缺少了类似“IsTextAvailable”的方法(参见问题的注释)。我接受了这个答案,因为它确认了我所做的事情是正确的,
IsTextElement
确实不足以满足我们的需求。
class function TXmlUtils.IsTextOrCDataElement(ANode: IXMLNode): Boolean;
begin
  Result := False;
  if ANode.ChildNodes.Count = 0 then begin
    if ANode.NodeType in [ntText, ntCData] then begin
      Result := True;
    end;
  end else
  if ANode.ChildNodes.Count = 1 then begin
    if ANode.ChildNodes.First.NodeType in [ntText, ntCData] then begin
      Result := True;
    end;
  end;
end;
? XML CDATA read