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

Render snake_case -> kebab-case #381

Closed
Przemek625 opened this issue Jan 10, 2021 · 3 comments
Closed

Render snake_case -> kebab-case #381

Przemek625 opened this issue Jan 10, 2021 · 3 comments
Labels
documentation Improvements or additions to documentation

Comments

@Przemek625
Copy link

Przemek625 commented Jan 10, 2021

Is it posible to easily set global rendering option that would change all field names from snake_case to kebab-case in generated xml? Now it required to set it manually with code like this:

from dataclasses import dataclass, field
@dataclass
class ContactPerson:
    given_names: str = field(metadata=dict(name="given-names"))

I dont see in method XmlSerializer.render any option that would allow me to achieve this goal.

It is very inconvenient at the moment when I have like 100 other fields of this kind...

@Przemek625 Przemek625 changed the title snake_case -> kebab-case Render snake_case -> kebab-case Jan 10, 2021
@tefra
Copy link
Owner

tefra commented Jan 10, 2021

It's not really documented because it was added in a hurry for something I needed but it's there.

The parser/serializer depend on XmlContext to provide binding information about the models. The XmlContext has an entry point to set a custom callable for element and attribute names if an implicit one is missing.

import sys
from dataclasses import dataclass, field
from datetime import date

from xsdata.formats.dataclass.context import XmlContext
from xsdata.formats.dataclass.parsers import XmlParser
from xsdata.formats.dataclass.serializers import XmlSerializer
from xsdata.formats.dataclass.serializers.config import SerializerConfig
from xsdata.utils.text import split_words, camel_case

def kebab_case(name: str) -> str:
    return "-".join(split_words(name))

@dataclass
class ContactPerson:
    first_name: str  # element
    last_name: str  # element
    birth_date: date = field(
        metadata=dict(
            type="Attribute",
            format="%Y-%m-%d"
        )
    )
    user_name: str = field(metadata=dict(name="avatar"))  # implicit field name

obj = ContactPerson(
    first_name="Chris",
    last_name="Tsoulloftas",
    birth_date=date(1986, 9, 25),
    user_name="Tefra",
)

# The context must now be passed to the xml parser/serializer
context = XmlContext(
    element_name=kebab_case,
    attribute_name=camel_case
)

config = SerializerConfig(pretty_print=True)
serializer = XmlSerializer(context=context, config=config)
parser = XmlParser(context=context)
serializer.write(sys.stdout, obj)
<Contact-Person birthDate="1986-09-25">
  <first-name>Chris</first-name>
  <last-name>Tsoulloftas</last-name>
  <avatar>Tefra</avatar>
</Contact-Person>

@tefra tefra added the documentation Improvements or additions to documentation label Jan 10, 2021
@Przemek625
Copy link
Author

@tefra thank you very much!

tefra added a commit that referenced this issue Jan 21, 2021
tefra added a commit that referenced this issue Jan 21, 2021
@tefra tefra closed this as completed in 79dcbfe Jan 21, 2021
@tefra
Copy link
Owner

tefra commented Jan 21, 2021

@Przemek625

The params to the XmlContext class will be renamed in the next version

context = XmlContext(
    element_name_generator=kebab_case,
    attribute_name_generator=camel_case
)

I also added those properties per model

https://xsdata.readthedocs.io/en/latest/models.html#customize-element-and-attribute-names

tefra added a commit that referenced this issue Jan 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

2 participants