pear XML_Serializer - 消除多余的标签

时间:2013-09-26 16:29:50

标签: php xml xml-serialization

我创建一个数组,然后将0..n个元素推送到数组中的一个子数组中 (最容易在下面的代码中看到我的意思)

当我通过XML_Serializer运行数组时,它会在推送的元素周围添加额外的标签

$serializer_options = array(
    XML_SERIALIZER_OPTION_INDENT => '    ',
    XML_SERIALIZER_OPTION_RETURN_RESULT => TRUE,
    rootName => 'JZ_2103'
);
$serializer = &new XML_Serializer($serializer_options);

$otXmlArr = array(
    'status' => 'success',
    'reason' => 'null',
    'payload' => array(
        'ContactsResponse' => array()
    )
);

foreach ($mydata as $item) {
    array_push($otXmlArr['payload']['ContactsResponse'],
        array(
            'Contact' => array(
                'ID' => $item['id'],
                'FirstName' => $item['fname']
            )
        )
    );
}

$otXml = $serializer->serialize($otXmlArr);

创建的xml具有额外标记<XML_Serializer_Tag>。如何消除这些标签?

<JZ_2103>
    <status>success</status>
    <reason>null</reason>
    <payload>
        <ContactsResponse>
            <XML_Serializer_Tag>
                <Contact>
                    <ID>10</ID>
                    <FirstName>Roy</FirstName>
                </Contact>
            </XML_Serializer_Tag>
        </ContactsResponse>
    </payload>
</JZ_2103>

Abstr的解决方案几乎可行 - 它产生:

来自数组的print_r:

Array
(
    [status] => success
    [reason] => null
    [payload] => Array
        (
            [ContactsResponse] => Array
                (
                    [0] => Array
                        (
                            [Contact] => Array
                                (
                                    [ID] => 3
                                    [FirstName] => Joe
                                )

                        )

                    [1] => Array
                        (
                            [Contact] => Array
                                (
                                    [ID] => 4
                                    [FirstName] => Fred
                                )

                        )

                )

        )

)

序列化XML:

<JZ_2103>
    <status>success</status>
    <reason>null</reason>
    <payload>
        <ContactsResponse>
            <Contact>
                <ID>3</ID>
                <FirstName>Joe</FirstName>
            </Contact>
        </ContactsResponse>
        <ContactsResponse>
            <Contact>
                <ID>4</ID>
                <FirstName>Fred</FirstName>
            </Contact>
        </ContactsResponse>
    </payload>
</JZ_2103>

使用Daniel的建议,XML输出是: 额外的嵌套水平: - (

<JZ_2103>
    <status>success</status>
    <reason>null</reason>
    <payload>
        <ContactsResponse>
            <Contact>
                <Contact>
                    <ID>3</ID>
                    <FirstName>Joe</FirstName>
                </Contact>
            </Contact>
            <Contact>
                <Contact>
                    <ID>4</ID>
                    <FirstName>Fred</FirstName>
                </Contact>
            </Contact>
        </ContactsResponse>
    </payload>
</JZ_2103>

我打算放弃使用序列化程序,我只想使用simpleXml直接构建xml。这一切都是为了节省一些时间,显然,它没有!

感谢Daniel和Abstr的帮助,即使它没有让我到达终点线。

4 个答案:

答案 0 :(得分:3)

'mode' => 'simplexml'添加到$ serializer_options应该:

$serializer_options = array(
    XML_SERIALIZER_OPTION_INDENT => '    ',
    XML_SERIALIZER_OPTION_RETURN_RESULT => TRUE,
    'rootName' => 'JZ_2103',
    'mode' => 'simplexml', 
);

或使用常数,

$serializer_options = array(
    XML_SERIALIZER_OPTION_INDENT => '    ',
    XML_SERIALIZER_OPTION_RETURN_RESULT => TRUE,
    XML_SERIALIZER_OPTION_ROOT_NAME => 'JZ_2103',
    XML_SERIALIZER_OPTION_MODE => XML_SERIALIZER_MODE_SIMPLEXML,
);

在第515行找到它here

  

//使用XML_SERIALIZER_MODE_SIMPLEXML将父名称用作标记名

     

//如果转换索引数组

XML_SERIALIZER_OPTION_MODE => XML_SERIALIZER_MODE_DEFAULT,

编辑:更新为指向实际的XML_Serializer代码库。

应按如下方式对代码进行更改(感谢@danielpsc,请参阅注释):

$otXmlArr = array(
    'status' => 'success',
    'reason' => 'null',
    'payload' => array(
        'ContactsResponse' => array(
            'Contact' => array()
        )
    )
);

foreach ($mydata as $item) {
    array_push($otXmlArr['payload']['ContactsResponse']['Contact'],
        array(
            'ID' => $item['id'],
            'FirstName' => $item['fname']
        )
    );
}

EDIT2 :对代码进行了更改

答案 1 :(得分:2)

$serializer_options = array(
    XML_SERIALIZER_OPTION_INDENT => '    ',
    XML_SERIALIZER_OPTION_RETURN_RESULT => TRUE,
    rootName => 'JZ_2103'
);
$serializer = &new XML_Serializer($serializer_options);

$otXmlArr = array(
    'status' => 'success',
    'reason' => 'null',
    'payload' => array(
        'ContactsResponse' => array()
    )
);

foreach ($mydata as $key => $item) {
    $otXmlArr['payload']['ContactsResponse']['contact_'.$key] = array(
          'ID' => $item['id'],
          'FirstName' => $item['fname']
      );
}

$otXml = $serializer->serialize($otXmlArr);

预期结果:

<JZ_2103>
    <status>success</status>
    <reason>null</reason>
    <payload>
        <ContactsResponse>
            <Contact_1>
                <ID>3</ID>
                <FirstName>Joe</FirstName>
            </Contact>
            <Contact_2>
                <ID>4</ID>
                <FirstName>Fred</FirstName>
            </Contact>
        </ContactsResponse>
    </payload>
</JZ_2103>

如果不是结果,请告诉我......

答案 2 :(得分:0)

我认为问题在于您的ContactResponses都在数字索引数组中,而XML不允许使用数字标记。如果您print_r数组,您会看到:

Array
(
    [status] => success
    [reason] => null
    [payload] => Array
        (
            [ContactsResponse] => Array
                (
                    [0] => Array  <---- ** The Problem **
                        (
                            [Contact] => Array
                                (
                                    [ID] => 1
                                    [FirstName] => daniel
                                )

                        ) ... etc ...

因此,XML_Serializer需要为这些数字标记赋予有效值 - 默认情况下,它选择使用XML_Serializer_Tag

您可以使用“defaultTagName”选项选择XML_Serializer用于匿名标记的名称,这样您就可以获得所需的结果:

$serializer_options = array(
    XML_SERIALIZER_OPTION_INDENT => '    ',
    XML_SERIALIZER_OPTION_RETURN_RESULT => TRUE,
    'defaultTagName'=>'Contact',
    'rootName' => 'JZ_2103'
);
$serializer = &new XML_Serializer($serializer_options);

$otXmlArr = array(
    'status' => 'success',
    'reason' => 'null',
    'payload' => array(
        'ContactsResponse' => array()
    )
);

foreach ($mydata as $item) {
    array_push($otXmlArr['payload']['ContactsResponse'],
        array(
            'ID' => $item['id'],
            'FirstName' => $item['fname']
        )
    );
}

$otXml = $serializer->serialize($otXmlArr);

所以在这里我将默认标签名称设置为Contact并删除了foreach循环中的“Contact”标签 - 这使得该标签获得了defaultTagName。

编辑编辑尝试让解释更清晰一点!

答案 3 :(得分:-2)

private void Form_Load(object sender,EventArgs e)

    {

        XmlDataDocument xmlDatadoc = new XmlDataDocument();

        xmlDatadoc.DataSet.ReadXml("C:\\path.xml");

        DataSet ds = new DataSet("Sample");

        ds = xmlDatadoc.DataSet;

        dataGridView1.DataSource = ds.DefaultViewManager;

        dataGridView1.DataMember = "Sample";

    }