Как вывести значения в определенных строчках?

xml code

<!--File Created By SMS Backup & Restore v10.06.120 on 31/05/2020 19:46:08-->
<smses count="6080" backup_set="41fdc96e-8cdc-42ac-b368-b2b1404264c7" backup_date="1250943591234"/>
  <sms protocol="0" address="+78898877767" date="1472878509996" type="1" subject="null" body="АУАУАУАУАУ Я ДОМА ТЫ ГДЕ ?" toa="null" sc_toa="null" service_center="+71111111111" read="1" status="-1" locked="0" date_sent="0" sub_id="1" readable_date="22 авг. 2016 г. 18:03:29" contact_name="user"/>

Мне надо, чтобы выводились значения аттрибутов body и contract_name. Просто всё писать в ручную долго и скучно


Ответы (1 шт):

Автор решения: return

Тут можно использовать стандартную библиотеку System.Xml.dll (.NET Framework) или стандартную платформу .NET Core App (.NET Core). Здесь 2 способа решения: относительный low-level или относительный high-level.

Решение

Типы

public sealed class Data
{
    public string? Body { get; set; }
    public string? ContractName { get; set; }
    // ...
}
public interface IDataProvider
{
    void ProvideData(Data data);
}
// Вы можете использовать вместо пути другой индефикатор ресурсов (что-то типо pack uri (ссылка #1))
public abstract class FileDataProvider : IDataProvider
{
    public string Path { get; }

    public FileDataProvider(string path) { /*...*/ }

    public Stream OpenRead() => File.OpenRead(Path);
    public abstract void ProvideData(Data data);
}
public sealed class XmlDataProvider : FileDataProvider
{
    public XmlDataProvider(string path) : base(path) { }

    public override ProvideData(Data data)
    {
        // код
    }
}

И тут происходит разделение на low-level и high-level.

Low-level

public bool TryProvideData(Data data)
{
    // checks

    using var stream = OpenRead();
    using var reader = XmlReader.Create(stream);

    if (reader.MoveToContent() != XmlNodeType.Element) return false;
    if (reader.Name != "smses") return false;
    if (!reader.Read()) return false;
    if (reader.NodeType != XmlNodeType.Element) return false;
    if (reader.Name != "sms") return false;

    while (true)
    {
        if (!reader.Read()) return false;
        if (reader.NodeType != XmlNodeType.Attribute) break;

        switch (reader.Name)
        {
            case "contract_name": data.ContractName = reader.Value; break;
            default: return false;
        }
    }

    data.Body = null;

    if (reader.NodeType != XmlNodeType.EndElement)
        data.Body = reader.ReadInnerXml();

    return true;
}
public override void ProvideData(Data data)
{
    var data = new Data();

    if (!TryProvideData(data)) /*throw*/;

    return data;
}

High-level

public override void ProvideData(Data data)
{
    var doc = XDocument.Load(Path);
    var smsNode = doc.Element("smses").Element("sms");
    data.ContractName = smsNode.Attribute("contract_name");
    data.Body = smsNode.CreateReader().ReadInnerXml();
}

Ссылки

→ Ссылка