Skip to content

XML Serialization: SerializedName("ElementName/@AttributeName") with XmlElement does not create an attribute #1601

@NikoGrano

Description

@NikoGrano

If a PHP class property is annotated with #[JMS\XmlElement] and #[JMS\SerializedName("ElementName/@AttributeName")], the XmlSerializationVisitor attempts to create an XML element literally named ElementName/@AttributeName instead of creating an element ElementName with an attribute AttributeName. This results in an "invalid tag name" error because / and @ are not valid characters in XML.

Interestingly, the deserialization process (XmlDeserializationVisitor) correctly handles this syntax, mapping an attribute from the XML to the corresponding PHP property using XPath. However, serialization fails to mirror this behavior.

To Reproduce Consider the following PHP class structure:

use JMS\Serializer\Annotation as Serializer;

/** @Serializer\XmlRoot("test-object") */
class MessageSenderDetails
{
    /**
     * @Serializer\SerializedName("FromIdentifier")
     * @Serializer\Type("string")
     * @Serializer\XmlElement(cdata=false)
     */
    public string $fromIdentifier;

    /**
     * @Serializer\SerializedName("FromIdentifier/@SchemeID")
     * @Serializer\Type("string")
     * @Serializer\XmlElement(cdata=false) // This, combined with SerializedName, is key
     */
    public ?string $fromIdentifierSchemeID = null;
}

// --- Test Code ---
// $serializer = SerializerBuilder::create()->build();
// $details = new MessageSenderDetails();
// $details->fromIdentifier = "SomeID";
// $details->fromIdentifierSchemeID = "Scheme123";
//
// $xml = $serializer->serialize($details, 'xml'); // This line throws an exception

Expected behavior The serializer should produce XML similar to:

<?xml version="1.0" encoding="UTF-8"?>
<test-object>
  <FromIdentifier SchemeID="Scheme123">SomeID</FromIdentifier>
</test-object>

Actual behavior: The serialization process throws an exception for the reasons mentioned at the start of this issue.

Environment

• JMS Serializer version: 3.x/master
• PHP version: 8.4

As additional context issue arises because XmlSerializationVisitor::visitProperty currently does not have specific logic to interpret the ElementName/@AttributeName pattern in serializedName (when xmlAttribute metadata is false and XmlElement is used) as an instruction to set an attribute on a previously serialized sibling element. Instead, it falls through to the standard element creation logic.

I plan to submit a Pull Request with an implementation for this feature shortly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions