views:

25

answers:

1

I try to achive the opposite of here. I have an abstract class, but I do not want the abstract class' type and tag to be outputted. So I need an output, which basically looks like

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dokument ausgabe="ausgabe_test.doc" vorlage="vorlage_test.dot">
    <marke typ="text" name="test">
        <text>This is a test</text>
    </marke>
</dokument>

rather than

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dokument ausgabe="ausgabe_test.doc" vorlage="vorlage_test.dot">
    <marke typ="text" name="test">
        <inhalt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="text">
            <text>This is a test</text>
        </inhalt>
    </marke>
</dokument>

Text is inherited from the abstract class Inhalt.

My current (generated) schema is shown below.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;

  <xs:element name="dokument" type="dokument"/>

  <xs:complexType name="dokument">
    <xs:sequence>
      <xs:element name="marke" type="marke" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="vorlage" type="xs:string" use="required"/>
    <xs:attribute name="ausgabe" type="xs:string" use="required"/>
  </xs:complexType>

  <xs:complexType name="marke">
    <xs:sequence>
      <xs:element name="inhalt" type="inhalt"/>
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" use="required"/>
    <xs:attribute name="typ" type="markenTyp" use="required"/>
  </xs:complexType>

  <xs:complexType name="inhalt" abstract="true">
    <xs:sequence/>
    <xs:attribute name="style" type="xs:string"/>
  </xs:complexType>

  <xs:complexType name="text">
    <xs:complexContent>
      <xs:extension base="inhalt">
        <xs:sequence>
          <xs:element name="text" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:simpleType name="markenTyp">
    <xs:restriction base="xs:string">
      <xs:enumeration value="text"/>
      <xs:enumeration value="tabelle"/>
      <xs:enumeration value="liste"/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>
A: 

Based on the schema you have supplied, I would say the following: remember that inheritance of complex types in XML Schema is not exactly the same as you would expect in Java.

In your schema/object model, you have a type inhalt and a type text that inherits from it. inhalt is abstract. So far, so good. The difference comes in the usage of the types. You assign the type inhalt to an element called inhalt. That means only the element inhalt can appear there, not text, and the xsi:type override is necessary to indicate which subtype is being used (the parser cannot guess it).

You can achieve what you want to achieve if you use a substitution group in addition to the sub-typing, this will allow the element text to appear. Refactor the schema as follows:

  1. Create a global element with name "inhalt", and type "inhalt" (make the type name upper case if you think this is confusing)
  2. Create a global element with name "text" and type "text". Set the substitution group attribute of "text" to "inhalt".
  3. Replace the local element reference in "marke" with a reference to the global element.

For reference, here is the new model of marke:

<xs:element name="inhalt" type="inhalt"/>
<xs:element name="text" type="text" substitutionGroup="inhalt"/>
<xs:complexType name="marke">
    <xs:sequence>
        <xs:element ref="inhalt"/>
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" use="required"/>
    <xs:attribute name="typ" type="markenTyp" use="required"/>
</xs:complexType>

After this, text can appear inside marke.

xcut
Thank you a lot. Though, I still need to read about substitution groups to understand them.
Jan