Самая сложная часть - получить правильный заказ от 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 inferred from an XML file - how to iterate through all the elements in the XSD? (вопрос Моравский, он ссылается в своем комментарии)
Capture Schema Information when validating XDocument (мой собственный вопрос & ответ)
In C#, how to determine the XSD-defined MaxLength for an element
http://geekswithblogs.net/.NETonMyMind/archive/2006/05/02/76957.aspx (Великий блоге, где я получил большую часть информации для моего SchemaInfo вопрос и ответ)
Конечно, вы можете просто переписать XML, поместив свой элемент 'XElement' в правильном порядке. Откуда вы знаете, что такое правильный порядок? Загрузив XSD в 'XmlSchema' и используя класс' XmlSchemaSequence'. См. Мой вопрос (и мой собственный ответ) http://stackoverflow.com/questions/7311880/xmlschema-inferred-from-an-xml-file-how-to-iterate-through-all-the-elements-in для более Информация. –
@Morawski Так что ваш код выполняется через каждый элемент и атрибут в проекте.Для моего примера 1,2,3, кажется, достаточно легко, но если бы существовала возможность появления элемента несколько раз, вам нужно было бы подсчитать, сколько раз элемент возникает и зацикливать этот номер? – Andy