你能改变XML以适应LINQ的XSD吗?

时间:2011-12-20 09:25:15

标签: c# xml linq xsd

我有一个需要重新排列元素的XML。有没有办法使用LINQ做到这一点?

如下例所示,元素3和2已混淆,需要重新排列,因此元素为1,2和3.可能在下次数据进入时,它将以不同的顺序排列,但是需要回到1,2和3。

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

1 个答案:

答案 0 :(得分:3)

最难的部分是从XSD获得正确的订单。您可以将XSD加载为XDocument并直接使用XML进行查询。

根据您的示例考虑以下架构(我添加了下划线,因为12,&amp; 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>    `

如果你把它加载到一个对象(XDocumentXElement是最好的),你可以对模式进行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(很棒的博客文章,我从我的SchemaInfo问题和答案获得了大部分信息)