Thomas Marti: Nur ein Attribut in XML-Schema definieren?

Hallo

Folgendes Problem: Ich möchte ein XML-Schema haben, dass nur ein
einzelnes Attribut deklariert, aber nicht festlegt in welchem Element, das dies nachher verwendet werden muss.

Ich hab mir das mal so zusammengestiefelt:

------- agnes.xsd --------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schematargetNamespace="http://agnes.sf.net/ns/agnes"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 elementFormDefault="qualified" xmlns="http://agnes.sf.net/ns/agnes">
 <xsd:complexType name="agnesType">
  <xsd:attribute name="id" type="idType"/>
 </xsd:complexType>
 <xsd:simpleType name="idType">
  <xsd:restriction base="xsd:token">
   <xsd:pattern value="AGID_[0-9a-zA-Z]{16}"/>
  </xsd:restriction>
 </xsd:simpleType>
</xsd:schema>
------- agnes.xsd --------------------------------------------------

Das sollte man nachher so verwenden können:

------- whatever.xsd -----------------------------------------------
<whatever xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:agnes="http://agnes.sf.net/ns/agnes"
 xsi:schemaLocation="http://agnes.sf.net/ns/agnes agnes.xsd"
 agnes:id="AGID_1234567890abcdef">
     <foo>
          <bar/>
     </foo>
</whatever>
------- whatever.xsd -----------------------------------------------

Der XMLSpy beschwert sich aber immer mit folgender Meldung zum Schema: 'No Content Model available for validation (possibly empty DTD/Schema)'

=> Tja nun ist die Frage: Wie erstelle ich eine Schema, welches nur ein einzelnes Attribut definiert??

Danke im voraus...

Gruss, Thomas

  1. Hallo,

    Folgendes Problem: Ich möchte ein XML-Schema haben, dass nur ein
    einzelnes Attribut deklariert,

    Wozu überhaupt nur ein einzelnes Attribut validieren wollen?

    aber nicht festlegt in welchem Element, das dies nachher verwendet werden muss.

    Das wir nicht gehen.
    Attribute können in der XML-Doku ja auch nicht allein ohne ein Elemente herumkugeln. Du muss das Attribut Elementen zuordnen sonst kann es auch nicht überprüft werden.

    <xsd:complexType name="agnesType">
      <xsd:attribute name="id" type="idType"/>
     </xsd:complexType>

    Damit hat du ein anonymen Typ definiert, nun muss du diesen Typ in deinen Elementen referenzieren.

    ------- agnes.xsd --------------------------------------------------
    <?xml version="1.0" encoding="UTF-8"?>
    <xsd:schematargetNamespace="http://agnes.sf.net/ns/agnes"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified" xmlns="http://agnes.sf.net/ns/agnes">

    Du müsstest auch attributeFormDefault="qualified" benutzen!

    Grüße
    Thomas

    1. Hallo

      Hallo Namensvetter ;)

      Merci für deine Antwort!

      Wozu überhaupt nur ein einzelnes Attribut validieren wollen?

      Ich muss wohl ein bisschen weiter ausholen und erklären was ich eigentlich damit bezwecke...

      Wir schreiben ein Framework mit dem man XML-Daten synchronisieren kann. Der Witz dabei ist, dass man beliebige XML-Schemas dafür verwenden kann und an diesen keine Änderungen machen muss. Trotzdem muss aber (quasi als eindeutigen Schlüssel) unsere ID in jedes XML-Dokument. Was ich nun gerne machen möchte, ist dass diese ID als Attribut bloss einmal in agnes.xsd definiert werden muss und jedes XML-Dokument dieses dann via Namespace einbindet. Aber eben der entscheidende Punkt ist, dass das Original-Schema nicht verändert wird! Deshalb würde es auch nichts bringen, unser Schema mit XLink oder so einzubinden...

      Darum die Frage: Ist dies so irgendwie möglich? Oder gibt es evtl. noch eine andere Möglichkeit?

      MfG
      Thomas Marti

      1. Hallo Thomas,

        Hallo Namensvetter ;)

        8-)

        Wozu überhaupt nur ein einzelnes Attribut validieren wollen?

        Ich muss wohl ein bisschen weiter ausholen und erklären was ich eigentlich damit bezwecke...

        Wir schreiben ein Framework mit dem man XML-Daten synchronisieren kann. Der Witz dabei ist, dass man beliebige XML-Schemas dafür verwenden kann und an diesen keine Änderungen machen muss. Trotzdem muss aber (quasi als eindeutigen Schlüssel) unsere ID in jedes XML-Dokument. Was ich nun gerne machen möchte, ist dass diese ID als Attribut bloss einmal in agnes.xsd definiert werden muss und jedes XML-Dokument dieses dann via Namespace einbindet.

        Hm...
        Wie gesagt, nur ein Attribut kann man nicht so einbinden. Natürlich kann man anonym Tpyen, oder globale Attribute definieren aber es muss zumindest einem Element zugewiesen bzw. in einem Element Deklaration referenziert werden.
        (OT: genau an diese Frage krankt die Schemavalidierung in Tamino, es fügt das Rootelement auch ein eigenes ID Attribut zu, was natürlich einer unabhängigen Schema dann wiederspricht)
        Es gibt aber in Schema kein wildcard für Elementnamen.

        Die einzige Lösung die mir jetzt einfällt, beinhaltet auch eine zumindest kleine Änderung der fremden Schema:

        -------- xml -----------
        <whatever
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:agnes="http://agnes.sf.net/ns/agnes"
         xsi:schemaLocation="http://agnes.sf.net/ns/agnes whatever.xsd"
         agnes:id="AGID_1234567890abcdef">
             <foo>
                  <bar/>
             </foo>
        </whatever>
        -------------------------

        ------ whatever.xsd ------
        <?xml version="1.0" encoding="ISO-8859-1"?>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
         <xs:import namespace="http://agnes.sf.net/ns/agnes" schemaLocation="agnes.xsd"/>
         <xs:element name="whatever">
          xs:complexType
           xs:sequence
            <xs:element name="foo">
             xs:complexType
              xs:sequence
               <xs:element name="bar">
                xs:complexType/
               </xs:element>
              </xs:sequence>
             </xs:complexType>
            </xs:element>
           </xs:sequence>
           <!-- hier muss das "Attribut" eingefügt werden -->
           <xs:anyAttribute processContents="strict" namespace="##targetNamespace" />
          </xs:complexType>
         </xs:element>
        </xs:schema>
        -----------------------
        ----- agnes.xsd -------
        <?xml version="1.0" encoding="UTF-8"?>
        <xsd:schema
         targetNamespace="http://agnes.sf.net/ns/agnes"
         xmlns="http://agnes.sf.net/ns/agnes"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
         elementFormDefault="qualified"
         attributeFormDefault="qualified">
         <xsd:complexType name="agnesType">
          <xsd:attribute name="id" type="idType" />
         </xsd:complexType>
         <xsd:simpleType name="idType">
          <xsd:restriction base="xsd:token">
           <xsd:pattern value="AGID_[0-9a-zA-Z]{16}"/>
          </xsd:restriction>
         </xsd:simpleType>
        </xsd:schema>

        Eine andere Lösung fällt mir da nicht ein, was natürlic nicht bedeutet, dass es keine geben könnte.

        Grüße
        Thomas

        PS: XMLSpay meckert weil für deine XML-Datei (whatever) keine DTD/SChema gab in dem die Elemente Deklariert wurden.