【问题标题】:Using XDocument to create schema ordered XML使用 XDocument 创建模式有序 XML
【发布时间】:2010-09-17 16:02:59
【问题描述】:

我目前正在尝试找到一种按模式顺序向现有 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 那样容易xml 中可能包含也可能不包含的 100 个可选元素。

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

有没有办法做到这一点,还是我不走运?

【问题讨论】:

    标签: c# xsd linq-to-xml


    【解决方案1】:

    我最终使用了一些将节点转换为自身但已排序的 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()));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多