Непустая IXMLNodeCollection.Count возвращает 0

#xml #delphi

#xml #delphi

Вопрос:

У меня есть XSD от третьей стороны, и я использовал инструмент привязки данных XML для создания из него классов. Инструмент привязки данных не включал префикс, но я могу решить это в двух частях.

  1. Добавление префикса n1 к TagName параметру of GetDocBinding приводит к тому, что все дочерние элементы наследуют префикс, кроме дочерних узлов any IXMLNodeCollection . Например
 function NewMYDOCUMENT: IXMLMYDOCUMENT;
begin
  Result := NewXMLDocument.GetDocBinding('n1:MYDOCUMENT', TXMLMYDOCUMENT, TargetNamespace) as IXMLMYDOCUMENT;
end;
  
  1. Добавление префикса в AfterConstruction любой IXMLNodeCollection
 procedure TXMLAllowanceCollection.AfterConstruction;
begin
  RegisterChildNode('n1:Allowance', TXMLAllowance);
  ItemTag := 'n1:Allowance';
  ItemInterface := IXMLAllowance;
  inherited;
end;
  

После выполнения обоих шагов сгенерированный XML соответствует XSD, как того требует третья сторона, однако я не могу перебирать элементы в AllowanceCollection . AllowanceCollection.Count возвращает 0 независимо от количества дочерних узлов и AllowanceCollection.Allowance[X] выдает исключение, даже если X это допустимый индекс.

Если я удалю оба n1 префикса из № 2, дочерние узлы AllowanceCollection не будут иметь n1 префикса. Если я удалю только один из них, я получу EIntfCastError Interface not supported исключение. Включение любого значения в NamespaceURI параметр of RegisterChildNode не имеет никакого эффекта.

До сих пор мне приходилось прибегать к n1 полному удалению префикса и переопределению GetXML для вставки префикса

 function TXMLMYDOCUMENT.GetXML: DOMString;
begin
  Result := TRegEx.Replace(inherited, '(<(/)?)', '1n1:');
  Result := TRegex.Replace(Result, 'xmlns=', 'xmlns:n1=');
end;

  

Комментарии:

1. IIRC, структура привязки данных XML не очень хорошо поддерживает пространства имен XML.

2. Да, когда инструмент привязки данных XML сгенерировал классы, он не включил пространства имен, поэтому мне пришлось добавлять их вручную. Мне интересно, является ли потенциальным решением удаление пространств имен и «вручную» добавление их в сгенерированный XML

3. Я думаю, вам нужно обновить сгенерированные по умолчанию оболочки привязки данных, чтобы использовать NamespaceURI параметр при вызове RegisterDocBinding() , и RegisterChildNode() тогда вы сможете использовать префиксы в именах узлов

4. Проблема не в получении префикса в именах узлов, я могу это сделать, введя abc: имя при вызове RegisterChildNode() . Проблема заключается в доступе к элементам IXMLNodeCollection , если коллекция имеет префикс. Я решил проблему, полностью удалив пространство имен и префикс, а затем вставив префикс обратно в сгенерированную строку XML (т. Е. заменив < and </ на <abc: and </abc: соответственно)

5. как я уже сказал, если вы правильно зарегистрируете пространство имен, тогда вы сможете использовать префиксы естественным образом и не должны использовать обходной путь для введения префикса после факта