У меня есть простой код обработки XML, который должен найти дочерний узел переданного узла на основе значения атрибута:
function GetNodeByAttributeValue(
const AParentNode: IXMLNode;
const AttributeName: string; AttributeValue: Variant): IXMLNode;
var
i: integer;
value: Variant;
begin
result := nil;
if (not Assigned(AParentNode)) or (AttributeName = '') then
exit;
for i := 0 to AParentNode.ChildrenCount-1 do
begin
result := AParentNode.Children[i];
value := result.GetAttributeValue(AttributeName, UnAssigned);
if not VarIsEmpty(value) then
exit;
end;
result := nil;
end;
Довольно просто, правда? Но когда я пытаюсь запустить это, при определенных обстоятельствах происходит сбой с нарушением прав доступа. Вот что происходит:
Реализация IXML* предоставляется библиотекой RemObjects SDK. result.GetAttributeValue
звонит uROMSXMLImpl.TROMSXMLNode.GetAttributeValue
, который звонит TROMSXMLNode.GetAttributeByName
, который говорит
node := fNode.attributes.getNamedItem(anAttributeName);
И это вылетает, потому что fNode.attributes
возвращает nil. Как я понимаю, такого быть не должно.
Странно то, что возвращаясь к циклу for исходной функции, AParentNode.ChildrenCount
возвращает 3. Но узел в исходном XML-документе имеет только один дочерний узел. Он соответствует критериям, которые я ищу.
<ParentNode>
<namespace:ChildNode name="right-name">
Но AParentNode.ChildrenCount
возвращает 3. Открываю их в отладчике и получаю вот это:
AParentNode.Children[0].name: '#text'
AParentNode.Children[1].name: 'namespace:ChildNode'
AParentNode.Children[2].name: '#text'
Что это за узлы "#text"? Их нет в XML-документе, и я не писал никакого кода для их вставки. Почему они здесь, и почему они глючат, и могу ли я что-нибудь сделать, чтобы они не испортили мой поиск атрибутов?