为什么';t IXMLNode.IsTextElement是否为CDATA元素返回True?
我们正在使用Delphi2007和为什么';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
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节点还是文本节点,只需使用Delphiis
操作符即可。还有一个类似于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