Это является продолжением моей предыдущей публикации: String to XmlNode Delphi (or how to add an xml fragment to TXMLDocument) Это представляется целесообразным, чтобы начать новый вопрос ...Delphi Исключение при Сохраняя Whitespace в TXMLDocument
Я по существу добавление хорошо сформированные XML-фрагменты в существующий XmlDocument , Код, предложенный в предыдущем решении, отлично работал - до тех пор, пока я не добавил [poPreserveWhiteSpace] в TXMLDocument.ParseOptions.
Когда я удаляю [poPreserveWhiteSpace], все работает отлично, но пробелы не сохраняются. Он фактически помещает закрывающий тег в новую строку.
Вот фрагмент кода из целевого документа TXMLDocument.
StoredXMLObj := TXMLDocument.Create(self);
StoredXMLObj.Options := [doNodeAutoCreate, doNodeAutoIndent];
StoredXMLObj.ParseOptions := StoredXMLObj.ParseOptions + [poPreserveWhiteSpace];
StoredXMLObj.XML.Assign(StoredXML); //StoredXML is a TStringList with a complete XML Document
StoredXMLObj.Active := TRUE;
Я пробовал разные комбинации вариантов и ParseOptions выше, но я могу только получить код для работы путем удаления [poPreserveWhiteSpace].
код, который вызывает исключение является второй строкой:
tmpNode := storedXMLObj.DocumentElement.ChildNodes[i]; // <Class> node
tmpNode.ChildNodes.Nodes[1].ChildNodes.Nodes[0].ChildNodes.Add(LoadXMLData(MissingElements[j]).DocumentElement); //TMPNode is an IXMLNode and MissingElements is a TStringList
Я попытался создать ссылку на возвращаемом значение LoadXMLData (..), и установке этих ParseOptions, чтобы соответствовать, прежде чем добавлять XML фрагмент, но не повезло и там.
Любые мысли?
Редактировать: добавление самодостаточного образца кода для демонстрации проблемы. Уточненное название. Вот несколько упрощенных кодов. Обратите внимание, что будет исключение, если вы не закомментируете строку, содержащую [poPreserveWhitespace]. ** Edit2: Тонкая настройка кода для сохранения пробелов в соответствии с предложением Реми. Все еще проблема при вызове FormatXMLData.
procedure TForm2.BitBtn2Click(Sender: TObject);
var
FragmentXMLObj : TXMLDocument;
StoredXMLObj : TXMLDocument;
FragNode : IXMLNode; //THIS SHOULD BE IXMLNODE, RIGHT?
XMLStarting, XMLFragment, XMLMerged : TStringList;
i : integer;
begin
//StringLists to hold xml data
XMLStarting := TStringList.Create; //COMPLETE XML
XMLFragment := TStringList.Create; //XML FRAGMENT TO INSERT INTO COMPLETE XML
XMLMerged := TStringList.Create; //MERGE OF THE ABOVE TWO.
//STARTING XML
XMLStarting.Add('<?xml version="1.0" encoding="UTF-16" standalone="no"?>');
XMLStarting.Add('<Programs>');
XMLStarting.Add(' <Program_Group Batch_No="{12345678-1234-1234-1234-123456789ABC}" Description="FOO_824_1">');
XMLStarting.Add(' <Program Name="PROG_1">');
XMLStarting.Add(' <Class Name="CLASS_1">');
XMLStarting.Add(' <Property Name="DB" RttiType="tkString"> </Property>');
XMLStarting.Add(' <Property Name="SystemDate" RttiType="tkClass" ClassType="TXSDATE">12/30/1899</Property>');
XMLStarting.Add(' </Class>');
XMLStarting.Add(' </Program>');
XMLStarting.Add(' </Program_Group>');
XMLStarting.Add('</Programs>');
//XML DOCUMENT OBJECT
StoredXMLObj := TXMLDocument.create(self);
//PROBLEM LINE START
StoredXMLObj.ParseOptions := StoredXMLObj.ParseOptions + [poPreserveWhiteSpace];
//PROBLEM LINE END
StoredXMLObj.Options := [doNodeAutoCreate, doNodeAutoIndent];
StoredXMLObj.XML.Text := XMLStarting.Text;
StoredXMLObj.Active := TRUE;
//XML FRAGMENT WITH SPACES
XMLFragment.Add('<ParentNode>');
XMLFragment.Add('<Property Name="VRSN" RttiType="tkString"> </Property>');
XMLFragment.Add('<Property Name="ShowMetaData" RttiType="tkBoolean"> </Property>');
XMLFragment.Add('</ParentNode>');
//--OLD CODE THAT RAISES EXCEPTION--
//INSERTING XML FRAGMENT INTO STARTING XML
// FragNode := storedXMLObj.DocumentElement.ChildNodes[0];
// FragNode.ChildNodes.Nodes[0].ChildNodes.Nodes[0].ChildNodes.Add(LoadXMLData(XMLFragment.Text).DocumentElement.ChildNodes.Nodes[0]);
// FragNode.ChildNodes.Nodes[0].ChildNodes.Nodes[0].ChildNodes.Add(LoadXMLData(XMLFragment.Text).DocumentElement.ChildNodes.Nodes[1]);
//--OLD CODE THAT RAISES EXCEPTION--
FragNode := storedXMLObj.DocumentElement.ChildNodes[1];
FragmentXMLObj := TXMLDocument.Create(self);
FragmentXMLObj.ParseOptions := FragmentXMLObj.ParseOptions + [poPreserveWhiteSpace];
FragmentXMLObj.Options := [doNodeAutoCreate, doNodeAutoIndent];
FragmentXMLObj.LoadFromXML(XMLFragment.Text);
//FragNode.ChildNodes.Nodes[1].ChildNodes.Nodes[1].ChildNodes.Add(FragmentXMLObj.DocumentElement); //this also pulls in the parent tags, which I don't want.
for i := 0 to FragmentXMLObj.DocumentElement.ChildNodes.Count-1 do //easier to just pull in all the nodes (including whitespace, then formatxml to cleanup).
FragNode.ChildNodes.Nodes[1].ChildNodes.Nodes[1].ChildNodes.Add(FragmentXMLObj.DocumentElement.ChildNodes.Nodes[i]);
FragmentXMLObj.Free;
XMLMerged.Text := StoredXMLObj.XML.Text;
XMLMerged.Text := FormatXMLData(XMLMerged.Text); //UGH... FormatXMLData WIPES OUT WHITESPACE PROPERTY VALUES!! Doesn't seem to have any settings either...
XMLMerged.SaveToFile('c:\merged.xml');
XMLStarting.Free;
XMLFragment.Free;
XMLMerged.Free;
StoredXMLObj.Free;
end;
результирующий слитый файл XML ... Пробелы значения свойства получили уничтожены при форматировании (и мне нужно форматировать данные, OTW это действительно некрасиво).
<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<Programs>
<Program_Group Batch_No="{12345678-1234-1234-1234-123456789ABC}" Description="FOO_824_1">
<Program Name="PROG_1">
<Class Name="CLASS_1">
<Property Name="DB" RttiType="tkString"/>
<Property Name="SystemDate" RttiType="tkClass" ClassType="TXSDATE">12/30/1899</Property>
<Property Name="VRSN" RttiType="tkString"/>
<Property Name="ShowMetaData" RttiType="tkBoolean"/>
</Class>
</Program>
</Program_Group>
</Programs>
Элементы, которые я добавляю, являются точно такими же хорошо сформированными элементами, как раньше. Мне непонятно, почему добавление сохранения белого пространства изменило бы поведение TXMLDocument. – sse
Я тестировал код, используя те же элементы, что и раньше, и они были добавлены отлично с сохранением пробелов и без них. –
Как я уже сказал, когда я попытался добавить новые узлы с сохранением пробелов, включенными в пункте назначения, это сработало для меня. Так происходит что-то еще. –