function fixSequence(model, parsedXSD) {
  const { elementsByTagName } = parsedXSD,
        xsdSchema = elementsByTagName[ 'xsd:schema' ][ 0 ];

  const xsdComplexTypes = findChildren(xsdSchema, matchPattern({ tagName: 'xsd:complexType' }));

  if (!xsdComplexTypes) {
    return;
  }

  xsdComplexTypes.forEach(xsdComplexType => {

    // (1) find sequences
    const xsdSequences = findChildren(xsdComplexType, matchPattern({ tagName: 'xsd:sequence' }));

    if (!xsdSequences) {
      return;
    }

    const xsdSequence = xsdSequences[ 0 ];

    // (2) find elements in sequence
    const xsdElements = findChildren(xsdSequence, matchPattern({ tagName: 'xsd:element' }));

    if (!xsdElements) {
      return;
    }

    // (3) find corresponding type
    const type = model.types.find(matchPattern({ name: xsdComplexType.name.slice(1) }));

    if (!type) {
      return;
    }

    // (4) fix sequence of type properties
    type.properties = type.properties
      .map(property => {

        // (4.1) find corresponding element
        const xsdElement = xsdElements.find(({ name, ref }) => name === property.name || ref === property.name);

        if (xsdElement) {

          // (4.1.1) return index of found corresponding element
          return {
            index: xsdElements.indexOf(xsdElement),
            name: property.name
          };
        } else {

          // (4.1.2) find substitute
          const matcher = matchPattern({
            tagName: 'xsd:element',
            type: `t${ property.type }`
          });

          const substitutes = findChildren(xsdSchema, child => {
            return matcher(child) && child.substitutionGroup;
          });

          if (substitutes) {
            const substitute = substitutes[ 0 ];

            // (4.1.3) find substitutable
            const substitutable = xsdElements.find(matchPattern({ ref: substitute.substitutionGroup }));

            if (substitutable) {
              const index = xsdElements.indexOf(substitutable);

              // (4.1.4) return index of found substitutable
              return {
                substituteFor: substitutable.ref,
                index,
                name: property.name
              };
            }
          }
        }

        // (4.2) return maximum index if index not specified in sequence
        return {
          index: type.properties.length - 1,
          name: property.name
        };
      })
      .sort((a, b) => {
        return a.index - b.index;
      })
      .map(({ name }) => {
        return type.properties.find(matchPattern({ name }));
      });
  });

  return model;
}
/**
* Fix order of properties according to <sequence> indicators specified in XSD.
*
* Example:
*
* <xsd:complexType name="tDecisionRule">
*   <xsd:complexContent>
*     <xsd:extension base="tDMNElement">
*       <xsd:sequence>
*         <xsd:element name="inputEntry" />
*         <xsd:element name="outputEntry" />
*         ...
*       </xsd:sequence>
*     </xsd:extension>
*   </xsd:complexContent>
* </xsd:complexType>
*
* specifies that inputEntry elements must appear before outputEntry elements.
*
* @param {Object} model
* @param {Object} parsedXSD
*
* @returns {Object}
*/
Fix order of properties according to  indicators specified in XSD.
Example.



specifies that inputEntry elements must appear before outputEntry elements.
Fix order of properties according to indicators specified in XSD . Example . specifies that inputEntry elements must appear before outputEntry elements .
function fixSequence(model, parsedXSD) {
  const { elementsByTagName } = parsedXSD,
        xsdSchema = elementsByTagName[ 'xsd:schema' ][ 0 ];
  const xsdComplexTypes = findChildren(xsdSchema, matchPattern({ tagName: 'xsd:complexType' }));
  if (!xsdComplexTypes) {
    return;
  }
  xsdComplexTypes.forEach(xsdComplexType => {
    const xsdSequences = findChildren(xsdComplexType, matchPattern({ tagName: 'xsd:sequence' }));
    if (!xsdSequences) {
      return;
    }
    const xsdSequence = xsdSequences[ 0 ];
    const xsdElements = findChildren(xsdSequence, matchPattern({ tagName: 'xsd:element' }));
    if (!xsdElements) {
      return;
    }
    const type = model.types.find(matchPattern({ name: xsdComplexType.name.slice(1) }));
    if (!type) {
      return;
    }
    type.properties = type.properties
      .map(property => {
        const xsdElement = xsdElements.find(({ name, ref }) => name === property.name || ref === property.name);
        if (xsdElement) {
          return {
            index: xsdElements.indexOf(xsdElement),
            name: property.name
          };
        } else {
          const matcher = matchPattern({
            tagName: 'xsd:element',
            type: `t${ property.type }`
          });
          const substitutes = findChildren(xsdSchema, child => {
            return matcher(child) && child.substitutionGroup;
          });
          if (substitutes) {
            const substitute = substitutes[ 0 ];
            const substitutable = xsdElements.find(matchPattern({ ref: substitute.substitutionGroup }));
            if (substitutable) {
              const index = xsdElements.indexOf(substitutable);
              return {
                substituteFor: substitutable.ref,
                index,
                name: property.name
              };
            }
          }
        }
        return {
          index: type.properties.length - 1,
          name: property.name
        };
      })
      .sort((a, b) => {
        return a.index - b.index;
      })
      .map(({ name }) => {
        return type.properties.find(matchPattern({ name }));
      });
  });
  return model;
}
function fixSequence ( model , parsedXSD ) { const { elementsByTagName } = parsedXSD , xsdSchema = elementsByTagName [ 'xsd:schema' ] [ 0 ] ; const xsdComplexTypes = findChildren ( xsdSchema , matchPattern ( { tagName : 'xsd:complexType' } ) ) ; if ( ! xsdComplexTypes ) { return ; } xsdComplexTypes . forEach ( xsdComplexType => { const xsdSequences = findChildren ( xsdComplexType , matchPattern ( { tagName : 'xsd:sequence' } ) ) ; if ( ! xsdSequences ) { return ; } const xsdSequence = xsdSequences [ 0 ] ; const xsdElements = findChildren ( xsdSequence , matchPattern ( { tagName : 'xsd:element' } ) ) ; if ( ! xsdElements ) { return ; } const type = model . types . find ( matchPattern ( { name : xsdComplexType . name . slice ( 1 ) } ) ) ; if ( ! type ) { return ; } type . properties = type . properties . map ( property => { const xsdElement = xsdElements . find ( ( { name , ref } ) => name === property . name || ref === property . name ) ; if ( xsdElement ) { return { index : xsdElements . indexOf ( xsdElement ) , name : property . name } ; } else { const matcher = matchPattern ( { tagName : 'xsd:element' , type : ` ${ property . type } ` } ) ; const substitutes = findChildren ( xsdSchema , child => { return matcher ( child ) && child . substitutionGroup ; } ) ; if ( substitutes ) { const substitute = substitutes [ 0 ] ; const substitutable = xsdElements . find ( matchPattern ( { ref : substitute . substitutionGroup } ) ) ; if ( substitutable ) { const index = xsdElements . indexOf ( substitutable ) ; return { substituteFor : substitutable . ref , index , name : property . name } ; } } } return { index : type . properties . length - 1 , name : property . name } ; } ) . sort ( ( a , b ) => { return a . index - b . index ; } ) . map ( ( { name } ) => { return type . properties . find ( matchPattern ( { name } ) ) ; } ) ; } ) ; return model ; }
Fix order of properties according to <sequence> indicators specified in XSD.
Fix order of properties according to <sequence > indicators specified in XSD .
// (1) find sequences
 // (2) find elements in sequence
 // (3) find corresponding type
 // (4) fix sequence of type properties
 // (4.1) find corresponding element
 // (4.1.1) return index of found corresponding element
 // (4.1.2) find substitute
 // (4.1.3) find substitutable
 // (4.1.4) return index of found substitutable
 // (4.2) return maximum index if index not specified in sequence
