Можете ли вы изменить XML, чтобы он соответствовал XSD с LINQ? - PullRequest
0 голосов
/ 20 декабря 2011

У меня есть XML, который нуждается в перестановке элементов. Есть ли способ сделать это с помощью LINQ?

Как и в приведенном ниже примере, элементы 3 и 2 были перепутаны, и их необходимо переставить, чтобы элементы были 1,2 и 3. Вероятно, в следующий раз, когда поступят данные, они будут в другом порядке, но будут нужно вернуть на 1,2 и 3.

<a>
  <1></1>
  <3></3>
  <2></2>
</a>

1 Ответ

3 голосов
/ 20 декабря 2011

Самое сложное - получить правильный заказ от XSD. Вы можете загрузить XSD как XDocument и запросить его напрямую с XML.

Рассмотрим следующую схему на основе вашего примера (я добавил подчеркивание, поскольку 1, 2, & 3 сами по себе не являются допустимыми именами XML)

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="XMLSchema1"
    targetNamespace="http://tempuri.org/XMLSchema1.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema1.xsd"
    xmlns:mstns="http://tempuri.org/XMLSchema1.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>

  <xs:complexType name="a">
    <xs:sequence>
      <xs:element name="_1" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="_2" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="_3" type="xs:string" minOccurs="1" maxOccurs="1" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>    `

Если вы загрузите это в объект (лучше всего XDocument или XElement), вы можете выполнить запрос LINQ для схемы (запрос не тестировался, я делаю это из памяти в последний раз, когда я это делал это, но если я что-то упустил, это должно указать вам правильное направление)

var schema = XDocument.Load(@"C:\somepath\XMLSchema1.xsd");
var xs = XNamespace.Get(@"http://www.w3.org/2001/XMLSchema");

var order = (from x in schema.Elements(xs + "schema").Elements(xs + "complexType") 
             where x.Attributes("name").FirstOrDefault().Value == "a" 
             select x.Element(xs + "sequence").Elements())
            .First()
            .Select(x => x.Attribute("name").Value);

Если у вас более сложный XSD с предопределенными типами и / или настраиваемыми пространствами имен, это усложнит запрос, чтобы получить порядок элементов, но, надеюсь, вы поймете идею. Если у вас чрезвычайно сложный XSD, см. Некоторые ссылки, приведенные в конце этого ответа, чтобы помочь в понимании объектной модели XmlSchemaInfo, и вы можете написать собственный запрос, чтобы упростить получение заказа.

Если у вас правильный порядок, я не рекомендую использовать LINQ для фактического изменения порядка узлов, поскольку LINQ не был предназначен для изменения объектов, а скорее использовал его для поиска узлов и родительского узла, а затем переставил их в том порядке, в каком вы хотите.

XElement xelem = // get parent element of the elements you need to rearrange

foreach (var element in order)
{
    var node = xelem.Element(element);
    node.Remove();
    xelem.Add(node);                
}

, если вы собираетесь часто получать прямой доступ к XSD в коде, я рекомендую прочитать следующие вопросы и ответы для справки, поскольку объектная модель XmlSchemaInfo недостаточно хорошо документирована, и потребуется некоторое время и усилия, чтобы получить выполнимый метод, чтобы извлечь то, что вам нужно. Будет легче найти и извлечь необходимую информацию из схемы.

XmlSchema, выведенный из файла XML - как перебрать все элементы в XSD? (вопрос Моравского, на который он ссылается в своем комментарии)

Информация о схеме захвата при проверке XDocument (мой собственный вопрос и ответ)

В C #, как определить XSD-определенный MaxLength для элемента

http://geekswithblogs.net/.NETonMyMind/archive/2006/05/02/76957.aspx (Отличное сообщение в блоге, откуда я получил большую часть информации для моего вопроса и ответа в SchemaInfo)

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