Frage

Ich arbeite mit einigen XML-„Schnipseln“, die Elemente im XML bilden.Ich habe das Schema, kann diese Dateien jedoch nicht validieren, da es sich nicht um vollständige XML-Dokumente handelt.Diese Snippets werden mit den notwendigen übergeordneten Elementen umschlossen, um gültiges XML zu bilden, wenn sie in anderen Tools verwendet werden. Daher habe ich nicht viele Möglichkeiten, sie in gültiges XML umzuwandeln oder das Schema zu ändern.

Ist es möglich, ein Element statt des gesamten Dokuments zu validieren?Wenn nicht, welche Problemumgehungen könnten vorgeschlagen werden?

Ich arbeite in C# mit dem .NET 2.0 Framework.

War es hilfreich?

Lösung

Ich hatte ein ähnliches Problem, wo ich nur Teile meines XML-Dokument validieren kann. Ich kam mit dieser Methode hier oben:

private void ValidateSubnode(XmlNode node, XmlSchema schema)
{
    XmlTextReader reader = new XmlTextReader(node.OuterXml, XmlNodeType.Element, null);

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ConformanceLevel = ConformanceLevel.Fragment;
    settings.Schemas.Add(schema);
    settings.ValidationType = ValidationType.Schema;
    settings.ValidationEventHandler += new ValidationEventHandler(XSDValidationEventHandler);

    using (XmlReader validationReader = XmlReader.Create(reader, settings))
    {     
        while (validationReader.Read())
        {
        }
    }
}

private void XSDValidationEventHandler(object sender, ValidationEventArgs args)
{
    errors.AppendFormat("XSD - Severity {0} - {1}", 
                        args.Severity.ToString(), args.Message);
}

Im Grunde gibt es ihm ein XmlNode (was ich aus dem gesamten XmlDocument wähle mittels .SelectSingleNode) und ein XML-Schema, das ich aus einer eingebetteten Ressource XSD lade in meiner App. Jegliche Validierungsfehler, die gestopft in einen „Fehler“ String-Builder können auftreten werden, die ich dann am Ende ausgelesen, um zu sehen, ob es irgendwelche Fehler aufgezeichnet, oder nicht.

Werke für mich - die Leistung kann variieren: -)

Andere Tipps

Es gibt eine XmlDocument.Validate Methode, die ein XmlNode als Argument ein nimmt validiert nur dieser Knoten. Das mag sein, was Sie suchen ...

Ok, hier ist ein anderer Ansatz:

Sie können Ihre Schemadatei mit Hilfe eines XSLT-Transformation in ein neues Schema umwandeln, die Ihre Schnipsel Elemente als Wurzel hat. Sagen Sie Ihre ursprüngliche Schema wäre

<xs:schema id="MySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="RootElement">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="NestedElement">
          <xs:complexType>
            <xs:attribute name="Name" type="xs:string" use="required"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Sie haben Auszüge Typ NestedElement, die Sie überprüfen möchten:

<NestedElement Name1="Name1" />

Dann könnten Sie eine XSLT-Vorlage wie

verwenden
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="xs:element[@name='NestedElement']"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:schema id="MySchema">
      <xsl:copy-of select="."/>
    </xs:schema>
  </xsl:template>
</xsl:stylesheet>

Um ein neues Schema zu erstellen, die als root NestedElement hat. Das resultierende Schema würde wie folgt aussehen

<xs:schema id="MySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="NestedElement">
    <xs:complexType>
      <xs:attribute name="Name" type="xs:string" use="required" />
    </xs:complexType>
  </xs:element>
</xs:schema>

Sie können dann einen Schnipsel Dokument gegen dieses neue Schema einen Code wie

bestätigen Sie mit
XmlSchema schema;
using (MemoryStream stream =    new MemoryStream())
using (FileStream fs = new FileStream("MySchema.xsd", FileMode.Open))
using(XmlReader reader = XmlReader.Create(fs)) {
  XslCompiledTransform transform = new XslCompiledTransform();
  transform.Load("SchemaTransform.xslt");
  transform.Transform(reader, null, stream);
  stream.Seek(0, SeekOrigin.Begin);
  schema = XmlSchema.Read(stream, null);
}
XmlDocument doc = new XmlDocument();
doc.Schemas.Add(schema);
doc.Load("rootelement.xml");
doc.Validate(ValidationHandler);

MySchema.xsd ist das ursprüngliche Schema, SchemaTransform.xslt die Transformation (wie oben dargestellt), rootelement.xml ist ein XML-Dokument eines einzelnen Schnipsel Knoten enthält.

Sie können einen speziellen Namespace-Alias ​​verwenden, um die Elemente zu markieren, die Sie validieren möchten, und dann nur Schema für diesen Namespace-Alias ​​hinzufügen, nicht jedoch für andere.Auf diese Weise werden nur die Elemente mit Ihrem speziellen Namespace-Präfix validiert.

Es ist nicht nicht möglich sein zu tun, was ich zu tun streben. Meine aktuelle Arbeit ist um ein leeres Vorlage XML-Dokument zu erstellen. Dann ersetzen Sie das gewünschte Element mit meinem Schnipsel. Von dort, glaube ich, die Validate-Methode dann lebensfähig wäre. Aber diese Vorlage zu erstellen scheint dynamisch eine andere schwierige Aufgabe in seinem eigenen Recht zu sein. Es scheint nicht, eine einfache Möglichkeit zu sein, ein ‚Skelett‘ Dokument zu erstellen.

Ich hatte das gleiche Problem. Auch hier Lösung gefragt. Ich habe eine Abhilfe gefunden.

Das Problem ist, dass nur Stammelemente validiert werden können. Also ... ich das Schema IN MEMORY bearbeiten und fügen Sie das Element / Typ an der Wurzel bestätigen

public static void AddElementToSchema(XmlSchema xmlSchema, string elementName, string elementType, string xmlNamespace)
{
    XmlSchemaElement testNode = new XmlSchemaElement();
    testNode.Name = elementName;
    testNode.Namespaces.Add("", xmlNamespace);
    testNode.SchemaTypeName = new XmlQualifiedName(elementType, xmlNamespace);
    xmlSchema.Items.Add(testNode);
    xmlSchema.Compile(XMLValidationEventHandler);
}

Nur ein paar Zeilen, und Sie müssen keine XSD-Dateien nicht ändern oder hinzufügen :) Mit dieser einfachen Änderung Ihres In-Memory-Schema können Sie das Fragment mit dem gleichen Code validieren Sie ein vollständiges Dokument zu validieren verwenden. Seien Sie sicher, dass das Wurzelelement des Fragments zu validieren den Namespace enthält. :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top