2010-09-17 29 views
1

我目前正在试图找到一种方法,以架构顺序为现有的xml文档添加一些额外的元素。使用XDocument来创建架构有序的XML

的XML连接到它的模式,但我一直无法找到一种方式来获得的XDocument操作,以符合模式的顺序。

实施例模式提取

<xs:element name="control" minOccurs="1" maxOccurs="1"> 
    <xs:complexType> 
    <xs:sequence> 
     <xs:element name="applicationId" type="xs:unsignedByte" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="originalProcId" type="xs:unsignedByte" minOccurs="0" maxOccurs="1" /> 
     <xs:element name="dateCreated" type="xs:date" minOccurs="0" maxOccurs="1" /> 
     <xs:element name="requestId" type="xs:string" minOccurs="0" maxOccurs="1" /> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 

示例XML输入

<?xml version="1.0" encoding="utf-8" ?> 
<someDocument xmlns="urn:Test"> 
    <control> 
    <applicationId>19</applicationId> 
    <dateCreated>2010-09-18</dateCreated> 
    </control> 
    <body /> 
</someDocument> 

实施例的代码段

XDocument requestDoc = XDocument.Load("control.xml"); 

XmlSchemaSet schemas = new XmlSchemaSet(); 
schemas.Add("urn:MarksTest", XmlReader.Create("body.xsd")); 

// Valid according to the schema 
requestDoc.Validate(schemas, null, true); 

XElement controlBlock = requestDoc.Descendants("control").First(); 

controlBlock.Add(new XElement("originalProcId", "2")); 
controlBlock.Add(new XElement("requestId", "TestRequestId")); 

// Not so valid 
controlBlock.Validate(controlBlock.GetSchemaInfo().SchemaElement, schemas, null, true); 

我需要添加OriginalProcId和的requestId元素,但它们需要去Control元素中的特定位置,而不仅仅是最后一个孩子,当然它不是就像在前一个元素上执行AddAfterSelf一样简单,因为我只是害怕100个可选元素,这些元素可能会或可能不在xml中。

我已经尝试使用Validate method将架构验证信息集嵌入到XDocument中,我认为可能会这样做,但它似乎对元素插入位置没有影响。

有没有办法做到这一点还是我的运气?

回答

0

我结束了一些XLST是转化的节点本身,而是下令这样做,这里是代码

// Create a reader for the existing control block 
var controlReader = controlBlock.CreateReader(); 

// Create the writer for the new control block 
XmlWriterSettings settings = new XmlWriterSettings { 
    ConformanceLevel = ConformanceLevel.Fragment, Indent = false, OmitXmlDeclaration = false }; 

StringBuilder sb = new StringBuilder(); 
var xw = XmlWriter.Create(sb, settings); 

// Load the style sheet from the assembly 
Stream transform = Assembly.GetExecutingAssembly().GetManifestResourceStream("ControlBlock.xslt"); 
XmlReader xr = XmlReader.Create(transform); 

// Load the style sheet into the XslCompiledTransform 
XslCompiledTransform xslt = new XslCompiledTransform(); 
xslt.Load(xr); 

// Execute the transform 
xslt.Transform(controlReader, xw); 

// Swap the old control element for the new one 
controlBlock.ReplaceWith(XElement.Parse(sb.ToString()));