Как перебрать XDocument, получив полную структуру XML, объект за объектом? - PullRequest
4 голосов
/ 11 января 2010

У меня есть XmlDocument, который я могу пройти с XmlNode или преобразовать в XDocument и пройти через LINQ.

<Dataset>
    <Person>
        <PayrollNumber>1234567</PayrollNumber>
        <Surname>Smith-Rodrigez</Surname>
        <Name>John-Jaime-Winston Junior</Name>
        <Skills>
            <Skill>ICP</Skill>
            <Skill>R</Skill>
        </Skills>
        <HomePhone>08 8888 8888</HomePhone> 
        <MobilePhone>041 888 999</MobilePhone>
        <Email>curly@stooge.com</Email>
    </Person>
    <Person>
        <PayrollNumber>12342567</PayrollNumber>
        <Surname>Smith-Rodrigez</Surname>
        <Name>Steve</Name>
        <Skills>
            <Skill>Resus</Skill>
            <Skill>Air</Skill>
        </Skills>
        <HomePhone>08 8888 8888</HomePhone> 
        <MobilePhone>041 888 999</MobilePhone>
        <Email>curly@stooge.com</Email>
    </Person>
</Dataset>

Вопрос 1

Я хочу преобразовать записи / узлы Person в XML в объект бизнес-объекта (POCO). Поэтому я должен перебирать узел Person за раз, а затем анализировать отдельные значения. Этот последний бит интересен сам по себе, но сначала я должен получить фактические записи Person. У меня проблема в том, что если я выбираю по отдельным узлам (скажем, скажем XmlList в XmlDocoment).

Я собираю все поля по имени. Я заинтересован в том, чтобы сделать это в случае, если один из узлов человека неполон или даже отсутствует, и тогда я не буду знать, чего не хватает, когда я прохожу и собираю поля в бизнес-объектах. Я постараюсь проверить - см. Вопрос 2.

Я понимаю, что это можно сделать с помощью размышлений, но мне интересно.

Я пытался выполнить итерацию по объекту Person:

Вариант 1:

foreach (XObject o in xDoc.Descendants("Person"))
{
    Console.WriteLine("Name" + o);
    // [...]
}

Это дает мне записи из 2 человек (правильные), каждая из которых представляет собой строковый полный XML-документ, отформатированный в виде XML-документа. Просто подмножество вышеуказанного XML-документа.

Но как разделить запись сейчас на отдельные узлы или поля - желательно настолько безболезненно, насколько это возможно?

Вариант 2:

foreach (XElement element in xDoc.Descendants("Person"))
{
    // [...]
}

Это возвращает мне узлы XML - только значения - для каждого человека в одной строке, например,

1234567Смит-РодригезДжон-Хайме-Уинстон МладшийУровень 5, Центральная городская башня 2, 121 Король Уильям Сент-Северный Аделаида 5000ICPR08 8888 8888041 888 999111111curly@stooge.comE

Опять же, мало пользы.

Вопрос 2

Я могу легко проверить XDocument, есть несколько хороших примеров в MSDN, но я хотел бы знать, как я могу пометить неправильную запись. В идеале я хотел бы иметь возможность отфильтровывать хорошие записи в новые XDocument на лету, оставляя старые. Это возможно?

Ответы [ 2 ]

4 голосов
/ 11 января 2010

Проблема в том, что вы просто распечатываете элементы в виде строк. Вам нужно написать код для преобразования XElement из <Person> в ваш бизнес-объект. По общему признанию я ожидал бы полный XML, который будет записан вместо этого - Вы уверены, что не печатаете XElement.Value (который объединяет все нисходящие текстовые узлы)?

(Я не уверен в ответе на ваш второй вопрос - я предлагаю вам задать его как отдельный вопрос, чтобы мы не получили смесь ответов на одной странице.)

1 голос
/ 18 сентября 2010

Почему бы не использовать десериализацию XML?

Есть два способа сделать это.

  • Первый - изменить бизнес-объект Person для соответствия данному XML , добавив соответствующие атрибуты к классу Person и его свойствам. XML довольно прост, поэтому, вероятно, вам просто придется изменить имена, если между свойствами объекта и узлами XML нет совпадения 1: 1. Например, вы должны указать [XmlArray("Skills")] и [XmlArrayItem("Skill)] для коллекции Skills.

  • Вторым является преобразование данного XML в тот, который соответствует сериализации вашего объекта Person по умолчанию, а затем десериализацию.

Второе решение также даст вам возможность очень легко фильтровать «плохие» записи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...