xsdata icon indicating copy to clipboard operation
xsdata copied to clipboard

Root element name seems irrelevant

Open lovette opened this issue 7 months ago • 2 comments

I'm using xsdata in a new project and noticed that XML is successfully parsed regardless of the root element name. If this is a feature and not a bug, is there an option to tell the parser to fail if the root element name doesn't match the dataclass (or Meta) name?

from dataclasses import dataclass

from xsdata.formats.dataclass.parsers import XmlParser
from xsdata.formats.dataclass.serializers import XmlSerializer


@dataclass
class Person:
    first_name: str
    last_name: str


obj = Person(first_name="Bob", last_name="Smith")
serializer = XmlSerializer()
print(serializer.render(obj))

This works as expected.

parser = XmlParser()
p = parser.from_string("<Person><first_name>Bob</first_name><last_name>Smith</last_name></Person>", Person)
print(p.first_name)

This does too, which surprised me.

parser = XmlParser()
p = parser.from_string("<Foo><first_name>Bob</first_name><last_name>Smith</last_name></Foo>", Person)
print(p.first_name)

lovette avatar May 10 '25 21:05 lovette

When you specifically pass the class you force the parser to use that class no matter what, if you want to enforce qname lookup, skip passing the target class.

from dataclasses import dataclass

from xsdata.formats.dataclass.parsers import XmlParser

@dataclass
class Person:
    first_name: str
    last_name: str


obj = Person(first_name="Bob", last_name="Smith")
parser = XmlParser()
p = parser.from_string("<Foo><first_name>Bob</first_name><last_name>Smith</last_name></Foo>")

# xsdata.exceptions.ParserError: No class found matching root: Foo

I can't remember exactly why I did that, I don't like it either, let me check again to see if we can tighten that up.

tefra avatar May 11 '25 08:05 tefra

Ok, thanks. The top-level element for a lot of the endpoints I'm consuming is <Response>, each with different child elements depending on the endpoint. Some endpoints return <STATUS> if the call is successful and <Response> if it fails. How can I limit the parser's lookup to the Response class for the specific endpoint invoked? For the status endpoints, currently I parse first with the success response class and if that fails due to an unrecognized element, parse again with the failed response class.

lovette avatar May 11 '25 12:05 lovette