When ref is used in the xsd definition, its type and namespace are parsed incorrectly.
attributeDefaultType adds default type="xsd:anySimpleType" to ref attributes which does(and should) not have type attribute itself.
3.2 If ref is present, then all of <simpleType>, form and type must be absent. #
deref copies source attributes(real.StartElement.Attr) without considering the namespace of name attribute. As XmlSchema spec states name is NCName (not QName), references across namespaces cannot be Normalized in XML level while conforming the spec.
I suggest:
- Add
not(hasAttr("", "ref")) check in attributeDefaultType
- Move/Integrate
flattenRef to Parse instead of Normalize (at least for refs to external namespace)
Reproducible code
a.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://example.com/a" targetNamespace="http://example.com/a">
<xsd:simpleType name="ST_Text">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:attribute name="value" type="ST_Text"/>
</xsd:schema>
b.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://example.com/b" xmlns:a="http://example.com/a" targetNamespace="http://example.com/b">
<xsd:import namespace="http://example.com/a" schemaLocation="a.xsd"/>
<xsd:complexType name="CT_Root">
<xsd:attribute ref="a:value"/>
</xsd:complexType>
</xsd:schema>
main.go:
package main
import (
_ "embed"
"encoding/xml"
"fmt"
"aqwari.net/xml/xsd"
)
//go:embed a.xsd
var a []byte
//go:embed b.xsd
var b []byte
func main() {
schema, err := xsd.Parse(a, b)
if err != nil {
panic(err)
}
for _, s := range schema {
if s.TargetNS == "http://example.com/b" {
attrs := s.FindType(xml.Name{Space: "http://example.com/b", Local: "CT_Root"}).(*xsd.ComplexType).Attributes
for _, attr := range attrs {
fmt.Printf("%+v %T\n", attr.Name, attr.Type)
}
}
}
}
Expected: {Space:http://example.com/a Local:value} *xsd.SimpleType (a:value with type a:ST_Text having Base: String)
Actual: {Space:http://example.com/b Local:value} xsd.Builtin ((b:)value with type AnySimpleType)
When
refis used in the xsd definition, its type and namespace are parsed incorrectly.attributeDefaultTypeadds defaulttype="xsd:anySimpleType"to ref attributes which does(and should) not have type attribute itself.derefcopies source attributes(real.StartElement.Attr) without considering the namespace ofnameattribute. As XmlSchema spec statesnameis NCName (not QName), references across namespaces cannot beNormalized in XML level while conforming the spec.I suggest:
not(hasAttr("", "ref"))check inattributeDefaultTypeflattenReftoParseinstead ofNormalize(at least for refs to external namespace)Reproducible code
a.xsd:
b.xsd:
main.go:
Expected:
{Space:http://example.com/a Local:value} *xsd.SimpleType(a:valuewith typea:ST_Texthaving Base:String)Actual:
{Space:http://example.com/b Local:value} xsd.Builtin((b:)valuewith typeAnySimpleType)