2011-12-20 14 views
0

私は要素の並べ替えが必要なXMLを持っています。 LINQを使ってこれを行う方法はありますか?LINQでXSDに合うようにXMLを変更できますか?

下の例のように、要素3と要素2が混在しており、要素が1,2,3になるように並べ替える必要があります。次回データが入った時点でも順序は変わります1,2,3に戻す必要があります。

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

もちろん、単純にXMLを書き換えて、サブ 'XElement'を正しい順序で並べ替えることができます。正しい注文が何であるかをどうやって知っていますか?あなたのXSDを 'XmlSchema'にロードし、' XmlSchemaSequence'クラスを使用します。私の質問(と自分の答え)を参照してくださいhttp://stackoverflow.com/questions/7311880/xmlschema-inferred-from-an-xml-file-how-to-iter-through-all-the-elements-in情報 –

+0

@Morawskiだから、あなたのコードは、プロジェクト内のすべての要素と属性を通して実行されます。私の1,2,3の例では十分に簡単だと思われますが、要素が複数回現れる可能性がある場合は、要素が何回発生したかを数えてその数をループする必要がありますか? – Andy

答えて

3

最も難しい部分が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?(彼のコメントでMorawskiの質問彼参照)

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(私は私のための情報のほとんどを持ってどこからグレートブログ投稿

+0

これをまだ見て、返事をいただきありがとうございます。 LINQクエリには、変更が必要な小さなものがありました。正解のために質問を更新したいのであれば、それを - > に変更する必要がありました。var order =(from x from schema.Elements(xs + "schema ").Elements(xs +" complexType ") ここでx.Attributes(" name ")。FirstOrDefault()。値==" a " select x.Element(xs +" sequence ")要素() .First() .Select(x => x.Attribute( "name")。Value); – Andy

+0

@Andy、感謝....固定されました。 – psubsee2003

関連する問題