Что не так с этим файлом или кодом?
Что происходит \ в чем разница? Я пытаюсь вернуть определенный узел из файла XML.
XML-файл:
<?xml version="1.0" encoding="utf-8"?>
<JMF SenderID="InkZone-Controller" Version="1.2">
<Command ID="cmd.00695" Type="Resource">
<ResourceCMDParams ResourceName="InkZoneProfile" JobID="K_41">
<InkZoneProfile ID="r0013" Class="Parameter" Locked="false" Status="Available" PartIDKeys="SignatureName SheetName Side Separation" DescriptiveName="Schieberwerte von DI" ZoneWidth="32">
<InkZoneProfile SignatureName="SIG1">
<InkZoneProfile Locked="False" SheetName="S1">
<InkZoneProfile Side="Front" />
</InkZoneProfile>
</InkZoneProfile>
</InkZoneProfile>
</ResourceCMDParams>
</Command>
<InkZoneProfile Separation="Cyan" ZoneSettingsX="0 0,005 " />
</JMF>
Код:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("C:\\test\\test.xml");
XmlNode root = xmlDoc.DocumentElement;
var parent = root.SelectSingleNode("/JMF/Command/ResourceCmdParams/InkZoneProfile/InkZoneProfile/InkZoneProfile/InkZoneProfile");
XmlElement IZP = xmlDoc.CreateElement("InkZoneProfile");
IZP.SetAttribute("Separation", x.colorname);
IZP.SetAttribute("ZoneSettingsX", x.colorvalues);
xmlDoc.DocumentElement.AppendChild(IZP);
xmlDoc.Save("C:\\test\\test.xml");
Var parent возвращает мне значение NULL. Я отладил, и root и xmlDoc имеют на своем внутреннем тексте XML Content. Но тест, выполненный здесь (выполненный пользователем @har07 по предыдущему вопросу: SelectSingleNode возвращает ноль, даже если управление пространством имен работает без проблем. https://dotnetfiddle.net/vJ8h9S
В чем разница между этими двумя? Они в основном следуют одному и тому же коду, но один работает, а другой нет.
При отладке я обнаружил, что root.InnerXml имеет загруженное содержимое само по себе (так же, как XmlDoc.InnerXml). Но InnerXml не реализует метод для SelectSingleNode. Я считаю, что если я сохраню это в строку, я, вероятно, потеряю отступ и т. Д.
Может кто-нибудь сказать мне, в чем разница или что не так? Спасибо! Пример XML: https://drive.google.com/file/d/0BwU9_GrFRYrTUFhMYWk5blhhZWM/view?usp=sharing
1 ответ
SetAttribute
не автоматически экранировать строку для вас. Поэтому он делает ваш XML-файл недействительным.
Из MSDN о XmlElement.SetAttribute
Любая разметка, такая как синтаксис, который должен быть распознан как ссылка на сущность, обрабатывается как буквальный текст и должна быть надлежащим образом экранирована реализацией, когда она записана.
Найдите в своем коде всю строку, содержащую SetAttribute
и использовать SecurityElement.Escape
чтобы избежать значения.
Например: измените эти строки:
IZP.SetAttribute("Separation", x.colorname);
IZP.SetAttribute("ZoneSettingsX", x.colorvalues);
Для того, чтобы:
using System.Security;
IZP.SetAttribute("Separation", SecurityElement.Escape(x.colorname));
IZP.SetAttribute("ZoneSettingsX", SecurityElement.Escape(x.colorvalues));
Если имя атрибута содержит какой-либо из <>"'&
Вы также должны избежать этого, как значение.
Замечания:
Вы должны удалить текущие xmls, которые вы создаете, используя старый код, потому что он недействителен, при загрузке он вызовет исключение.