UNC-Libraries / jquery.xmleditor

jQuery based XML editor plugin.
153 stars 71 forks source link

Abstract elements problem #100

Open khamyl opened 3 years ago

khamyl commented 3 years ago

Problem description

Is the editor dealing with abstract elements?

I have a quite complex XSD. I'll focus only to the problematic part of it.

The XML Schema

<?xml version="1.0" encoding="UTF-8"?>

...

<xs:schema>

...

<!-- the definition of abstract element-->
<xs:element name="model.respLike" abstract="true"/>

...

<!-- the reference to abstract element is used on several places -->
<xs:group name="model.biblPart">
    <xs:choice>
      <xs:element ref="ns1:model.respLike"/>
      <xs:element ref="ns1:model.imprintPart"/>
      <xs:element ref="ns1:series"/>
      <xs:element ref="ns1:meeting"/>
      <xs:element ref="ns1:relatedItem"/>
      <xs:element ref="ns1:edition"/>
      <xs:element ref="ns1:extent"/>
      <xs:element ref="ns1:idno"/>
    </xs:choice>
  </xs:group>

...

 <!-- element derived from abstract element and extended  -->
 <xs:element name="author" substitutionGroup="ns1:model.respLike">
   <xs:complexType>
     <xs:complexContent>
       <xs:extension base="ns1:macro.phraseSeq">
         <xs:attributeGroup ref="ns1:att.global.attributes"/>
         <xs:attributeGroup ref="ns1:att.canonical.attributes"/>
       </xs:extension>
     </xs:complexContent>
   </xs:complexType>
 </xs:element>

...
 <!--  abstract element used to define a complexType  -->
<xs:element name="titleStmt">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="ns1:title"/>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="ns1:model.respLike"/>
      </xs:sequence>
      <xs:attributeGroup ref="ns1:att.global.attributes"/>
    </xs:complexType>
  </xs:element>

The XML instance


...

<titleStmt>
  <title>Přemyšlování o dokonalosti křesťanské</title>
  <author>Jan Amos Komenský</author>
</titleStmt>

...

In the JSON generated by xsd2json.js script the <titleStmt> element 2. child is referring to the abstract element. As a result the renderChild() function is handling the <author> element as "without the defiition":

XMLElement.prototype.renderChild = function(childNode, recursive) {
  var elementsArray = this.objectType.elements; 
  if (elementsArray) {
    for ( var i = 0; i < elementsArray.length; i++) {
      var prefix = this.editor.xmlState.getNamespacePrefix(elementsArray[i].namespace);         
      if (prefix + elementsArray[i].localName == childNode.nodeName) {
        //console.log("With def.: ", childNode); //Khamyl
        var childElement = new XMLElement($(childNode), elementsArray[i], this.editor);
        childElement.render(this, recursive);
        this.addChildrenCount(childElement);
        return;
      }
    }
  }

  // Handle children that do not have a definition
  var childElement = new XMLUnspecifiedElement($(childNode), this.editor);
  childElement.render(this, recursive);
  this.addChildrenCount(childElement);
};

The questions are

bbpennel commented 3 years ago

@khamyl Would you be able to share the error message that you receive from the console?

There are a number of test cases and schemas in this project that include abstract elements (for example schema_sub.xsd and dc.xsd).

Type references are supposed to be applied to element definitions, for example here in the schema_processor. Similarly, abstract elements are supposed to be excluded from appearing as children of other elements here.

It may not currently be able to handle an abstract element definition being referenced as the child of another element, such as in titleStmt. I haven't tested this in a while, but based on skimming the implementation I would think that that child wouldn't show up at all, since I don't think the editor attempts to determine what subclasses of a definition inherit from an abstract reference like this.