1

この非常に単純な XML を逆シリアル化しようとしています。

<?xml version="1.0" encoding="utf-8"?>
<root>
    <namespace>foo</namespace>
    <resource>bar</resource>
    <description>baz</description>
    <arguments>
        <argument>
            <name>foo</name>
            <type>string</type>
            <description>foo</description>
        </argument>
        <argument>
            <name>bar</name>
            <type>string</type>
            <description>bar</description>
        </argument>
    </arguments>
</root>

何を試しても、配列は常に空になるため、引数要素をまたは任意の種類のコレクションarrayに逆シリアル化することはできません。ArrayCollection

/**
 * @Type("array<Model\Argument>")
 */
private $arguments;

/**
 * @Type("ArrayCollection<Model\Argument>")
 */
private $arguments;

どちらも空の配列になります。そこで、引数用に別のオブジェクトを作成してみました

したがって、元のプロパティは次のようになります

/**
 * @Type("Model\Arguments")
 */
private $arguments;

そしてクラス

class Arguments {
    /**
     * @Type("array<App\Blueprint\Model\Argument>")
     */
    private $arguments;

    /**
     * @return mixed
     */
    public function getArguments() {
        return $this->arguments;
    }

    /**
     * @param mixed $arguments
     */
    public function setArguments($arguments) {
        $this->arguments = $arguments;
    }
}

配列はまだ空です。しかし、タイプを に変更する@Type("App\Blueprint\Model\Argument")と、正しいオブジェクトが得られますが、最初のものだけです。

逆シリアル化ハンドラーを登録しようとすると、それが次のようSimpleXmlElementになり、It is not yet possible to assign complex types to properties警告が表示されるため、変更できません...

編集

今のところ、私は愚かな方法でそれを解決することができました:

$registry->registerHandler(
    'deserialization',
    'Model\Arguments',
    'xml',
    function(XmlDeserializationVisitor $visitor, $data, array $type, DeserializationContext $context) {
        $arguments = [];
        foreach($data->children() as $child) {
            $arguments[] = SerializerBuilder::create()
                ->build()
                ->deserialize($child->asXML(), 'Model\Argument', 'xml');
        }

        return $arguments;
    }
);

誰かがより良い解決策を持っている場合は、ここに残しておいてください。

4

2 に答える 2

4

あなたはかなり近かった。2 つの別個のクラスを定義する必要があります。

/**
 * @Type("Model\Arguments")
 */
public $arguments;
/**
 * @Type("array<Model\Argument>")
 * @XmlList(inline = true, entry = "argument")
 */
public $argument;

クラスの@XmlListプロパティに注意してください。Argumentゲッターとセッターも削除できます!

于 2016-04-05T14:17:35.267 に答える