Я новый пользователь на этом форуме и не очень опытный разработчик / программист. Прежде чем задать этот вопрос, я просмотрел Stack Overflow и некоторые ссылки, предложенные Microsoft, но не нашел того, что искал.
У меня есть следующий XML-файл:
<?xml version="1.0" standalone="no" ?>
<WndPos name="FrontEnd.Login" l="703" r="1264" t="323" b="909" />
<LayerManager />
<ViewLayers name="RoofLayout" roof="1" nlwalls="1">
<Layer level="-1" module="1" name="Walls" locked="0" visible="1" />
</ViewLayers>
<DirProfiles>
<ProfileInfo ProfileName="ControlCQFT" JobPath="C:\Jobs" DatabasePath="D:\Database\ControlCQFT" />
</DirProfiles>
<DirHistory>
<ProfileInfo Use="Job" Path="C:\Jobs" />
</DirHistory>
Мне нужно заменить весь узел <DirProfiles>
. Входящий узел может быть пустым, который выглядит как <DirProfiles />
. Новый узел, который я хочу вставить, имеет формат:
<DirProfiles>
<ProfileInfo ProfileName="Control1" JobPath="D:\Client1\JobsA" DatabasePath="D:\Database\Control1" />
. . . . .
</DirProfiles>
Я пытался решить проблему как простую замену строки, но я не получил нужного мне результата.
< Сильный > Edit: Извиняюсь, я не понял, что мой xml-файл - это фрагментный xml-документ, а не полный XML-файл согласно спецификации.
3 ответа
Учитывая, что ваш входной файл является искаженным XML-файлом, который не содержит корневого узла, вы можете обойти это с помощью небольшого количества манипуляций со строками.
Вот файл, который у вас есть:
<?xml version="1.0" standalone="no" ?>
<WndPos name="FrontEnd.Login" l="703" r="1264" t="323" b="909" />
<LayerManager />
<ViewLayers name="RoofLayout" roof="1" nlwalls="1">
<Layer level="-1" module="1" name="Walls" locked="0" visible="1" />
</ViewLayers>
<DirProfiles>
<ProfileInfo ProfileName="ControlCQFT" JobPath="C:\Jobs" DatabasePath="D:\Database\ControlCQFT" />
</DirProfiles>
<DirHistory>
<ProfileInfo Use="Job" Path="C:\Jobs" />
</DirHistory>
Вот как с этим работать:
var sourceFileName = @"C:\{path}\xml_fragments.txt";
var text = $"<root>{String.Join(Environment.NewLine, File.ReadLines(sourceFileName).Skip(1))}</root>";
var doc = XDocument.Parse(text);
doc.Root.Element("DirProfiles").Elements().Remove();
doc.Root.Element("DirProfiles").Add(
new XElement(
"ProfileInfo",
new XAttribute("ProfileName", "Control1"),
new XAttribute("JobPath", @"D:\Client1\JobsA"),
new XAttribute("DatabasePath", @"D:\Database\Control1")));
Это дает мне:
<root>
<WndPos name="FrontEnd.Login" l="703" r="1264" t="323" b="909" />
<LayerManager />
<ViewLayers name="RoofLayout" roof="1" nlwalls="1">
<Layer level="-1" module="1" name="Walls" locked="0" visible="1" />
</ViewLayers>
<DirProfiles>
<ProfileInfo ProfileName="Control1" JobPath="D:\Client1\JobsA" DatabasePath="D:\Database\Control1" />
</DirProfiles>
<DirHistory>
<ProfileInfo Use="Job" Path="C:\Jobs" />
</DirHistory>
</root>
См. Следующее:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
string xml = File.ReadAllText(FILENAME);
XElement doc = new XElement("Root");
doc.Add(XElement.Parse(xml));
XElement dirProfiles = doc.Descendants("DirProfiles").FirstOrDefault();
XElement profileInfo = dirProfiles.Element("ProfileInfo");
profileInfo.SetAttributeValue("ProfileName", "Control1");
profileInfo.SetAttributeValue("JobPath", @"D:\Client1\JobsA");
profileInfo.SetAttributeValue("DatabasePath", @"D:\Database\Control1");
}
}
}
Вы можете проанализировать XML-данные в модели класса C # и после этого изменить данные в соответствии с требованиями. После изменений вы можете снова преобразовать объект модели в XML и переписать строку XML в том же файле.
Перейдите по этой ссылке для создания структуры класса по доступному XML: https://www.c-sharpcorner.com/blogs/convert-xml-json-file-to-c-sharp-class
И использовать этот код для преобразования Xml в объект класса C #
public static T ConvertXmlToObject<T>(String xml)
{
T result = default(T);
try
{
using (TextReader reader = new StringReader(xml))
{
try
{
result =
(T)new XmlSerializer(typeof(T)).Deserialize(reader);
}
catch (InvalidOperationException)
{
// Throw message for invalid XML
}
}
}
catch (Exception ex)
{
}
return result;
}
Вызовите функцию как:
var entity = ConvertXmlToObject<ModelClass>(XMLString);
Используйте этот код, чтобы снова преобразовать объект в XML
public static string ConvertObjectToXML<T>(T ModelClass)
{
XmlSerializer xsObject = new XmlSerializer(typeof(T));
var inputObject = ModelClass;
var xmlString = "";
using (var sw = new StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(sw))
{
xsObject.Serialize(writer, inputObject);
xmlString = sw.ToString();
}
}
return xmlString;
}
Вызовите эту функцию как:
string xmlString = ConvertObjectToXML<ModelClass>(ModelClassObject);
Похожие вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.