Сериализатор JMS, десериализация и xpath - PullRequest
0 голосов
/ 21 мая 2018

Итак, у меня есть этот образец XML:

<a>
    <bb>
        <b><c>bc1</c></b>
        <b><c>bc2</c></b>
        <b><c>bc3</c></b>
    </bb>
    <cc>
        <bb>
            <b><c>cbc1</c></b>
            <b><c>cbc2</c></b>
            <b><c>cbc3</c></b>
        </bb>
    </cc>
</a>

И это две сущности.Родительская сущность:

<?php
final class A
{
    /**
     * @JMS\Type("array<B>")
     * @JMS\XmlList(entry="b")
     * @JMS\SerializedName("bb")
     */
    private $bb;
    /**
     * @JMS\Type("array<B>")
     * @JMS\XmlList(entry="b")
     * @JMS\SerializedName("cc/bb")
     */
    private $cc;
}

и дочерняя сущность:

final class B {
    /**
     * @var string
     *
     * @ORM\Column(type="string", length=24)
     * @JMS\Type("string")
     * @JMS\SerializedName("c")
     */
    private $c;
}

Проблема в том, что после десериализации моего xml

    $object = $this->serializer->deserialize($xml, A::class, 'xml');

я получил свойство bb гидратирован, как я и ожидал, но свойство cc пусто.

Вопрос в том, есть ли способ заполнить это поле без промежуточного класса / объекта?

1 Ответ

0 голосов
/ 09 августа 2018

Да, это можно сделать аналогично https://stackoverflow.com/a/51766169/2034213,, изменив проанализированные данные XML перед началом десериализации.Здесь вы должны использовать pre_deserialize слушателя для перемещения cc/bb, чтобы стать прямым потомком a с именем, например, ccbb, и изменить аннотацию $a на @JMS\SerializedName("ccbb")

Есть,однако одно болезненное отличие от другого вопроса, связанного выше: хотя с SimpleXML легко добавить простой элемент с текстовым содержимым, перемещение по поддереву элементов может быть выполнено только путем повторного создания элементов, один за другим .

...