我有一個XML需要它的元素重新排列。有沒有辦法使用LINQ來做到這一點?你可以通過LINQ更改XML以適應XSD嗎?
在下面的例子中,元素3和元素2已經混合在一起,需要重新排列,因此元素是1,2和3.可能在下一次數據進入時,它將以不同的順序排列,但是將需要放回1,2和3.
<a>
<1></1>
<3></3>
<2></2>
</a>
我有一個XML需要它的元素重新排列。有沒有辦法使用LINQ來做到這一點?你可以通過LINQ更改XML以適應XSD嗎?
在下面的例子中,元素3和元素2已經混合在一起,需要重新排列,因此元素是1,2和3.可能在下一次數據進入時,它將以不同的順序排列,但是將需要放回1,2和3.
<a>
<1></1>
<3></3>
<2></2>
</a>
最難的部分是從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問題和答案)
仍在考慮這一點,謝謝你的回覆,那麼預計會更困難。 LINQ查詢確實有一些小的事情需要改變,如果你想在你的問題中更新它的正確性,我不得不改變它 - > var order =(從schema.Elements(xs +「schema中的x 「).Elements(xs +」complexType「) 其中x.Attributes(」name「)。FirstOrDefault()。值==」a「 select x.Element(xs +」sequence「)。Elements()) 。First() .Select(x => x.Attribute(「name」)。Value); – Andy 2011-12-20 11:21:43
@安迪,謝謝....修正。 – psubsee2003 2011-12-20 11:42:41
當然,您可以通過簡單地重寫XML,將其子類'XElement'按正確順序排列。你怎麼知道正確的順序是什麼?通過將XSD加載到'XmlSchema'並使用'XmlSchemaSequence'類。看到我的問題(和我自己的答案)http://stackoverflow.com/questions/7311880/xmlschema-inferred-from-an-xml-file-how-to-iterate-through-all-the-elements-in for more信息。 – 2011-12-20 09:29:37
@Morawski所以你的代碼做的是貫穿項目中的每個元素和屬性。對於我的1,2,3示例來說,似乎很容易,但是如果元素有多次出現的可能性,您是否需要計算元素出現的次數並循環該數字? – Andy 2011-12-20 10:03:06