Использование XDocument для создания схемы упорядоченного XML - PullRequest
1 голос
/ 17 сентября 2010

В настоящее время я пытаюсь найти способ добавления некоторых дополнительных элементов в существующие документы 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 для встраивания информации проверки схемы, установленной в XDocument, и я подумал, что это может сработать, но, похоже, это не повлияет на расположение вставки элемента .

Есть ли способ сделать это или мне не повезло?

1 Ответ

0 голосов
/ 29 сентября 2010

В итоге я сделал это с помощью некоторого 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()));
...