We're using Delphi 2007 and the oxmldom
Open XML
provider.
A normal situations input file looks similar to this:
<root>
<child>Some Text</child>
</root>
Now we have to process an input file that uses the CDATA
node type:
<root>
<child><![CDATA[Some special Text]]></child>
</root>
Node.IsTextElement
suddenly returns False
, but Node.Text
still works as expected.
I know that IXMLNode.IsTextElement
is just a convenience method, but I find this behavior rather odd.
As a workaround we're now using this custom method:
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;
My question is: Why does IsTextElement
not work with CDATA
nodes and is there an easier workaround?
It doesn't return true for Cdata nodes because that's just not the way it was written. It's unfortunate because consumers of XML data generally shouldn't be concerned with how text is represented in the serialized data. Your alternative is fine.
As Ritsaert Hornstra wrote in comment CDATA is not TEXT node of DOM tree. It's CDATA node.
Text property is something different. E.g. when current node is an attribute, Text will probably return value of this attribute.
If you want to check if current node is CDATA node or TEXT node, simply use Delphi is
operator. There is also something like nodeType
property which you are using anyway :-)
If you want to check if current node is CDATA node or TEXT node, simply use Delphi is
operator. There is also something like nodeType
property which you are using anyway :-)
? XML CDATA read
来源:https://stackoverflow.com/questions/8416986/why-doesnt-ixmlnode-istextelement-return-true-for-cdata-elements