Question

Je travaille avec des « extraits » xml qui forment des éléments vers le bas du xml. Je le schéma, mais je ne peux pas valider ces fichiers, car ils ne sont pas complets documents XML. Ces extraits sont enveloppés avec les éléments parents nécessaires pour former xml valide lorsqu'ils sont utilisés dans d'autres outils, donc je ne l'option pas beaucoup en les rendant en xml valide ou en modifiant le schéma.

Est-il possible de valider un élément, plutôt que l'ensemble du document? Dans le cas contraire, ce que des solutions de contournement pourrait-on proposer?

Je travaille en C # avec le framework .NET 2.0.

Était-ce utile?

La solution

J'ai eu un problème similaire où je ne pouvais valider certaines parties de mon document XML. Je suis venu avec cette méthode ici:

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);
}

En fait, je le passe un XmlNode (que je choisis de l'ensemble XmlDocument au moyen de .SelectSingleNode), et un schéma XML qui je charge à partir d'un XSD de ressource incorporée dans mon application. Toute erreur de validation qui peuvent se produire sont bourrés dans un constructeur de chaîne « erreurs », que je puis lu à la fin, pour voir s'il y avait des erreurs enregistrées ou non.

fonctionne pour moi - votre kilométrage peut varier: -)

Autres conseils

Il existe une méthode de XmlDocument.Validate qui prend un XmlNode comme un argument valide que ce nœud. Cela peut être ce que vous cherchez ...

Ok, voici une autre approche:

Vous pouvez transformer votre fichier de schéma à l'aide d'une transformation XSLT dans un nouveau schéma qui a vos éléments de snippet en tant que root. Supposons que votre schéma d'origine serait

<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>

Vous avez des extraits de type NestedElement que vous souhaitez valider:

<NestedElement Name1="Name1" />

Ensuite, vous pouvez utiliser un modèle XSLT comme

<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>

Pour créer un nouveau schéma qui a NestedElement en tant que root. Le schéma résultant ressemblerait

<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>

Vous pouvez ensuite valider un document extrait contre ce nouveau schéma en utilisant un code comme

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 est le schéma d'origine, SchemaTransform.xslt est la transformation (comme indiqué ci-dessus), rootelement.xml est un document XML contenant un seul noeud de l'extrait.

Vous pouvez utiliser un alias d'espace de noms spécial pour affecter les éléments que vous souhaitez valider, puis ajoutez uniquement schéma pour cet alias d'espace de noms, mais pas pour d'autres. De cette façon que ces éléments avec votre préfixe d'espace de noms spécial seront validés obtenir.

Il ne semble pas impossible de faire ce que j'aspire à faire. Mon travail actuel est autour de créer un document xml modèle vierge. Ensuite, remplacez l'élément désiré avec mon extrait. A partir de là, je crois que la méthode validate serait alors viable. Mais pour créer ce modèle semble être dynamiquement une autre tâche ardue dans son propre droit. Il ne semble pas être un moyen facile de créer un document « squelette ».

J'ai eu le même problème. Même demandé ici pour la solution. J'ai trouvé une solution de contournement.

Le problème est que seuls les éléments racine peuvent être validés. Alors ... je modifier le schéma en mémoire et ajouter l'élément / le type de valider à la racine

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);
}

Juste quelques lignes et vous ne devez pas modifier ou ajouter des fichiers XSD :) Avec ce simple changement à votre schéma en mémoire, vous pouvez valider le fragment avec le même code que vous utilisez pour valider un document. Assurez-vous simplement que l'élément racine du fragment pour valider comprend l'espace de noms. :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top