3

我创建了一个数组,然后将 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 输出是: Extra level of nesting :-(

<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

4 回答 4

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 行找到它。

// 使用 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:对代码进行了更改

于 2013-10-08T08:10:31.980 回答
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>

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

于 2013-10-08T00:53:23.663 回答
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。

编辑编辑尝试使解释更清楚!

于 2013-10-03T12:16:54.313 回答
-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";

    }
于 2013-10-07T11:59:51.237 回答