@SaniaInf
.net developer, бывший препресс-програмист

Как получить атрибуты элементов при десериализации Excel XML файла?

У меня есть xml файл сохраненный из Excel
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
    xmlns:o="urn:schemas-microsoft-com:office:office"
    xmlns:x="urn:schemas-microsoft-com:office:excel"
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
    xmlns:html="http://www.w3.org/TR/REC-html40">
    ...
    <Worksheet ss:Name="Page1">
    ...
    </Worksheet>
</Workbook>

И модель для парсинга.
using System.Xml.Serialization;

[XmlRoot(ElementName = "Worksheet", Namespace = "urn:schemas-microsoft-com:office:spreadsheet")]
public class Worksheet
{
    [XmlAttribute(AttributeName = "Name", Namespace = "urn:schemas-microsoft-com:office:spreadsheet")]
    public string Name { get; set; }
}

[XmlRoot(ElementName = "Workbook", Namespace = "urn:schemas-microsoft-com:office:spreadsheet")]
public class Workbook
{
    [XmlElement(ElementName = "Worksheet", Namespace = "urn:schemas-microsoft-com:office:spreadsheet")]
    public List<Worksheet> Worksheet { get; set; }
}

Десериализовать я пробовал двумя способами.
Используя XmlNamespaceManager
var xml = File.ReadAllText("so.xml");
var nt = new NameTable();
var mgr = new XmlNamespaceManager(nt);
mgr.AddNamespace("o", "urn:schemas-microsoft-com:office:office");
mgr.AddNamespace("x", "urn:schemas-microsoft-com:office:excel");
mgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet");
mgr.AddNamespace("html", "http://www.w3.org/TR/REC-html40");

var ctxt = new XmlParserContext(nt, mgr, "", XmlSpace.Default);
var reader = XmlReader.Create(new StringReader(xml), null, ctxt);
var serializer = new XmlSerializer(typeof(Workbook));

var wb = serializer.Deserialize(reader) as Workbook;
var ws = wb.Worksheet.First();
Console.WriteLine(ws.Name); //ws.Name is null

И без него
var serializer = new XmlSerializer(typeof(Workbook));
using var fs = new FileStream("so.xml", FileMode.Open);

var wb = serializer.Deserialize(fs) as Workbook;
var ws = wb.Worksheet.First();
Console.WriteLine(ws.Name); //ws.Name is null

В любом случае атрибут Name недоступен.
Но если изменить объявление namespace
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
в xml на любое другое, атрибуты появляются.
Как нормально десериализовать xml, что бы атрибуты были доступны?
  • Вопрос задан
  • 39 просмотров
Решения вопроса 1
AshBlade
@AshBlade Куратор тега C#
Просто хочу быть счастливым
У Worksheet - нет неймспейса. В свойстве Namespace атрибута XmlRoot для соответствующего класса поставь пустую строку (null не работает)

[XmlRoot(ElementName = "Worksheet", Namespace = "")] /* Вот тут */
public class Worksheet
{
    [XmlAttribute(AttributeName = "Name", Namespace = "urn:schemas-microsoft-com:office:spreadsheet")]
    public string Name { get; set; }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы