Usare LINQ to XML per creare dinamicamente un file XSD con dati presi da un database

di Stefano Paterno, in LINQ, LINQ to XML,

A volte può essere necessario creare il contenuto di un file XSD dinamicamente. Poichè un file XSD altro non è che un file XML, possiamo ricorrere a LINQ to XML. In questo script vedremo come inserire degli elementi di tipo "enumeration" all'interno del tag "restriction".

Le enumeration permettono, nella fase di verifica del file XML, di controllare che l'utente abbia inserito solamente una delle opzioni proposte. Spesso si ha la necessità di creare questi elementi partendo da tabelle di sistema (Ragione Sociale, Comuni, etc.). Vediamo ora il file XSD di partenza senza gli elementi enumeration:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="contacts">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="contact">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="firstName" type="xs:string" />
              <xs:element name="lastName" type="xs:string" />
              <xs:element ref="personType" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="personType">
    <xs:annotation>
      <xs:documentation>vincolo</xs:documentation>
    </xs:annotation>
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <!--ENUMERATION Tipologie Persone-->
      </xs:restriction>
    </xs:simpleType>
  </xs:element>
</xs:schema>

All'interno del tag restriction è stata commentato l'area in cui si andranno a creare dinamicamente le enumeration. Innanzitutto,
carichiamo nella variabile xmlDoc, di tipo XDocument, il file XSD:

XDocument xmlDoc = 
XDocument.Load(
  Path.Combine(
    AppDomain.CurrentDomain.BaseDirectory, "XmlToSchema1.xsd"
  )
);

Per accedere puntualmente agli elementi dello Schema è necessario abbinare il loro nome al namespace indicato all'inizio del file (xmlns:xs=, xs contiene lo schema xml), questo argomento è stato dettagliato nello script #81;

Attraverso LINQ to XML creiamo la query che restituisce il contenitore personType:

var obj = (from s in xmlDoc.Descendants(xs + "element")
           where s.FirstAttribute.Value == "personType"
           where s.FirstAttribute.Name.LocalName != "ref"
           select s).FirstOrDefault();

senza s.FirstAttribute.Name.LocalName != "ref" la query avrebbe restituito anche l'elemento ref che serve per referenziare una sequence nello schema.
A questo punto non rimane che accedere al tag restriction, contenuto in obj, con un'altra query LINQ to XML per effettuare successivamente la creazione degli elementi di enumerazione:

var objrestriction = (from s in obj.Descendants(xs + "restriction")
                      select s).FirstOrDefault();

Attraverso il metodo Add dell'oggetto objrestriction (visto come XElement) potranno essere creati i nodi nel seguente modo (per semplicità creiamo direttamente i valori):

//Fare il ciclo per tutti gli elementi che si vogliono enumerare...
objrestriction.Add(
  new XElement(xs + "enumeration", new XAttribute("value","Persona Fisica")));
objrestriction.Add(
  new XElement(xs + "enumeration", new XAttribute("value","Persona Giuridica")));

dopo queste modifiche salviamo il file ed il risultato sarà il seguente.

<xs:element name="personType">
  <xs:annotation>
    <xs:documentation>vincolo</xs:documentation>
  </xs:annotation>
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:enumeration value="Persona Fisica" />
      <xs:enumeration value="Persona Giuridica" />
    </xs:restriction>
  </xs:simpleType>
</xs:element>

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi