2010-09-17 37 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()));