Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsing of element with substitutionGroup fails #588

Open
ArminWiebigke opened this issue Oct 7, 2022 · 0 comments
Open

Parsing of element with substitutionGroup fails #588

ArminWiebigke opened this issue Oct 7, 2022 · 0 comments

Comments

@ArminWiebigke
Copy link

Steps

Given a XSD with an abstract type, for which concrete elements are provided via substitutionGroup:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType name="AnimalType" abstract="true">
        <xs:sequence>
            <xs:element name="species" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="Animal" type="AnimalType" abstract="true"/>
    <xs:element name="Dog" substitutionGroup="Animal">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="AnimalType">
                    <xs:sequence>
                        <xs:element name="furColor" type="xs:string"/>
                    </xs:sequence>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>
    <xs:element name="Fish" substitutionGroup="Animal">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="AnimalType">
                    <xs:sequence>
                        <xs:element name="scalesColor" type="xs:string"/>
                    </xs:sequence>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="PetType">
        <xs:sequence>
            <xs:element ref="Animal"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="Pet" type="PetType"/>
</xs:schema>

Try to parse a valid XML file for that schema:

<Pet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Dog>
     <species>dog</species>
     <furColor>brown</furColor>
  </Dog>
</Pet>

Problem

Parsing fails with

scalaxb.ParserFailure: Error while parsing <Pet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Dog>
        <species>dog</species>
        <furColor>brown</furColor>
      </Dog>
    </Pet>: parser error "'Animal' expected but Dog found" while parsing /Pet/Dog

The generated parser for PetType tries to parse the abstract type directly, instead of the subtypes:

def parser(node: scala.xml.Node, stack: List[scalaxb.ElemName]): Parser[PetType] =
      phrase((scalaxb.ElemName(None, "Animal")) ^^
      { case p1 =>
      PetType(scalaxb.fromXML[AnimalType](p1, scalaxb.ElemName(node) :: stack)) })

Expected

The generated parser/writer should be able to handle all elements that are provided via substitutionGroup for the abstract type.

Notes

I took a look at the code an stumbled upon

 def isSubstitutionGroup(elem: ElemDecl) =
    elem.global && (elem.namespace map { x =>
      context.substituteGroups.contains((elem.namespace, elem.name))
    } getOrElse { false })

Why does this always return false if the namespace is None? Changing it to

elem.global && context.substituteGroups.contains((elem.namespace, elem.name))

results in the parser picking up the concrete types

def parser(node: scala.xml.Node, stack: List[scalaxb.ElemName]): Parser[PetType] =
      phrase((((scalaxb.ElemName(None, "Dog")) ^^ 
      (x => scalaxb.DataRecord(x.namespace, Some(x.name), scalaxb.fromXML[Dog](x, scalaxb.ElemName(node) :: stack)))) | 
      ((scalaxb.ElemName(None, "Fish")) ^^ 
      (x => scalaxb.DataRecord(x.namespace, Some(x.name), scalaxb.fromXML[Fish](x, scalaxb.ElemName(node) :: stack))))) ^^
      { case p1 =>
      PetType(p1) })

but the element loses its type:

case class PetType(Animal: scalaxb.DataRecord[Any])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant