Прекратить преобразование знака в объект HTML - PullRequest
1 голос
/ 24 июля 2011

Я пишу некоторый XML на PHP, который не проверяется, потому что закрывающий знак больше, чем элемент CDATA, преобразуется в сущность HTML.Код выглядит следующим образом:

$xml .= '<item number="'.$i.'">
                <sku>'.$this->get_product_sku($key, $value).'</sku>
                <description>
                    <![CDATA[
                    '.get_the_title($value['prodid']).'
                    ]]>
                </description> 
                <qty>'.$value['quantity'].'</qty>
                <price>'.$value['price'].'</price> 
                <extended>'.$value['quantity']*$value['price'].'</extended>
            </item>';

Полученный XML выглядит примерно следующим образом при распечатке с использованием var_dump или print_r:

<item number="2"> 
            <sku>45NK2</sku> 
            <description> 
                <![CDATA[
                Test Product
                ]]&gt;
            </description> 
            <qty>2</qty> 
            <price>1500.00</price> 
            <extended>3000.00</extended> 
        </item>

Закрывающие > виткив &gt; и XML не проверяется.Может кто-нибудь помочь мне решить эту проблему?

Спасибо!

РЕДАКТИРОВАТЬ: Вот вся функция, которая генерирует XML.Я только звоню и печатаю эту функцию.С строкой, которая делает ее недействительной, ничего не сделано.

function build_xml($p, $c)
{
    global $wpdb;

    // Make the billing and shipping data available
    $this->determine_shipping_details($p, $c);
    $this->determine_billing_details($p, $c);

    // Build the XML
    $xml = '<?xml version="1.0" ?>
        <orderdata batch="'.$p['id'].'">
            <order id="'.$p['id'].'">
                <orderdate>'.date('m/d/Y h:i:s', $p['date']).'</orderdate>
                <store>'.$this->store_id.'</store>
                <adcode>OL</adcode>
                <username>'.$this->username.'</username>
                <password>'.$this->password.'</password>
                <billingaddress>
                    <firstname>'.$this->billing_details['first_name'].'</firstname>
                    <lastname>'.$this->billing_details['last_name'].'</lastname>
                    <address1>'.$this->billing_details['address'].'</address1>
                    <city>'.$this->billing_details['city'].'</city>
                    <state>'.$this->billing_details['state'].'</state>
                    <zipcode>'.$this->billing_details['zip'].'</zipcode>
                    <country>'.$this->billing_details['country'].'</country>
                    <phone>'.$this->billing_details['phone'].'</phone>
                    <email>'.$this->billing_details['email'].'</email>
                </billingaddress>
                <shippingaddress>
                    <firstname>'.$this->shipping_details['first_name'].'</firstname>
                    <lastname>'.$this->shipping_details['last_name'].'</lastname>
                    <address1>'.$this->shipping_details['address'].'</address1>
                    <city>'.$this->shipping_details['city'].'</city>
                    <state>'.$this->shipping_details['state'].'</state>
                    <zipcode>'.$this->shipping_details['zip'].'</zipcode>
                    <country>'.$this->shipping_details['country'].'</country>
                    <phone>'.$this->shipping_details['phone'].'</phone>
                    <email>'.$this->shipping_details['email'].'</email>
                </shippingaddress>
                <orderdetails>';

    // Add the individual items' information to the XML
    $i = 1;
    foreach($c as $key => $value)
    {
        $xml .= '<item number="'.$i.'">
            <sku>'.$this->get_product_sku($key, $value).'</sku>
            <description>
                <![CDATA[
                '.get_the_title($value['prodid']).'
                ]]>
            </description> 
            <qty>'.$value['quantity'].'</qty>
            <price>'.$value['price'].'</price> 
            <extended>'.str_replace(stripslashes( get_option('wpsc_thousands_separator') ), '', trim(wpsc_currency_display($value['quantity']*$value['price'], array('display_currency_symbol' => false, 'display_decimal_point' => true, 'display_currency_code' => false, 'display_as_html' => false)))).'</extended>
        </item>';

        $i++;
    }

    // Add the order totals
    $xml .= '<subtotal>'.str_replace(stripslashes( get_option('wpsc_thousands_separator') ), '', trim(wpsc_currency_display($p['totalprice']-$p['wpec_taxes_total']-$p['base_shipping'], array('display_currency_symbol' => false, 'display_decimal_point' => true, 'display_currency_code' => false, 'display_as_html' => false)))).'</subtotal>
        <shipping code="'.'FEG'.'" rate="'.$p['base_shipping'].'" thirdparty="">'.'FEDEX GROUND SERVICE'.'</shipping> 
        <tax rate="'.$p['wpec_taxes_rate'].'">'.$p['wpec_taxes_total'].'</tax>
        <total>'.$p['totalprice'].'</total>
        <amountpaid>'.$p['totalprice'].'</amountpaid>
    </orderdetails>';

    // Close out the tags
    $xml .= '</order>
    </orderdata>';

    return $xml;
}

Ответы [ 4 ]

1 голос
/ 24 июля 2011

Когда я запускаю его на своем веб-сервере, он правильно отформатирован.Вы устанавливаете заголовок?Попробуйте header('Content-type: text/xml');<br> echo $xml;

0 голосов
/ 10 мая 2013

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

Решение очень простое. Проблема в том, что WordPress обрабатывает это как HTML, а не как скрипт, и преобразует больше, чем символ> в & gt. Оскорбительный код находится в /wp-includes/post-template.php и выглядит следующим образом:

function the_content($more_link_text = null, $stripteaser = false) {
$content = get_the_content($more_link_text, $stripteaser);
$content = apply_filters('the_content', $content);
/**   $content = str_replace(']]>', ']]&gt;', $content); */

Как вы можете заметить, последняя строка конвертируется]]> в]] & gt. Комментируя это, вы решите проблему.

0 голосов
/ 24 июля 2011

На основании информации, предоставленной вами в вашем вопросе, трудно сказать, почему результат искажен.

Таким образом, вам нужно пройтись по вашей программе и посмотреть каждую точку, где ваш XML собирается (уже является частью вашего вопроса) и обрабатывается далее вашей установкой WordPress с различными плагинами и темами.

Для этого необходимо понять, где могут появиться такие модификации.

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

Подведем итоги:

  1. Создание XML должно быть правильным из первых рук.
  2. XML может быть изменен WordPress.
  3. XML может быть изменен браузером.

Это может быть много точек для проверки:

1. Создание XML должно быть правильным из первых рук.

Прежде всего, я посмотрю только на возвращаемое значение get_the_title($value['prodid']), чтобы вы действительно знали, с чем имеете дело. Возможно, он уже содержит &gt;? Это объясняет, откуда этот единственный &gt; может появиться. Однако было бы допустимо использовать его в пределах <![CDATA[...]]>. Это просто для того, чтобы понюхать и понять, что может произойти позже.

Рядом с единственным значением, о котором идет речь, вы должны убедиться, что сам XML выглядит корректно перед тем, как обработает его в дальнейшем, что означает в конце функции. Вы можете сделать это путем вывода его перед возвратом из метода и завершения / выхода из приложения, чтобы предотвратить дальнейшую обработку:

echo "Test output:\n\n", $xml; die();

Тогда посмотрите на вывод. Это выглядит правильно? Неужели проблемный &gt; уже есть в конце рассматриваемого раздела cdata? Если да, вы знаете, что проблема уже внутри функции. Если нет, то вы знаете, что проблема не связана с рассматриваемой функцией и что XML-файл позже будет искажен. В зависимости от результата, вам нужно искать дефект.

2. XML может быть изменен WordPress.

В комментариях вы спрашивали:

Зачем фильтровать var_dump? Я запускаю это в плагине, который я строю. Не уверен, почему это будет отфильтровано.

Помимо фильтрации, выполняемой программой (браузер, программа просмотра исходного кода и т. Д.), Сама WordPress или один из его дополнений (плагинов, тем) может фильтровать вывод. Из вашего комментария вы уже говорите, что не знаете, почему это может произойти, поэтому вы также не знаете, где это может произойти.

Вы еще не поделились тем, как выводится xml. Вы просто отображаете это в браузере? Это передается какой-то функции, которая обрабатывает вывод? Скорее всего, очень важно найти причину вашей проблемы. Например, ваш плагин отвечает на запрос XMLRPC? В своем вопросе вы много внимания уделяете недопустимому XML, но вы не делились большой информацией о том, для чего создается XML, куда он идет и по какой причине и т. Д. Эта информация будет полезна для понимания увеличенное изображение.

Если вы позаботитесь о выводе самостоятельно (echo, print и т. Д.), Возможно, в некотором коде установлен буфер вывода. Это означает, что ваши выходные данные буферизуются и, вероятно, обрабатываются позже. Эти проблемы с выходным буфером труднее отследить. Прежде всего вы можете отключить все другие плагины и темы и посмотреть, что произойдет. Wordpress сам по себе не использует буферизацию вывода ( Управление буферизацией вывода [Docs] ), так что это может довольно быстро затормозить, потому что тогда только буферизация вывода по умолчанию будет мешать вашему выводу.

Если вы используете функцию wordpress для вывода XML, тогда фильтры могут быть в действии.Wordpress имеет встроенную систему фильтров, которая позволяет подключать и изменять различные данные.Кроме того, основные функции Wordpress всегда «стараются» избежать выхода.Так что на самом деле может быть много точек, где эта фильтрация действительно имеет место. «Не уверен, почему это будет отфильтровано». - Может быть, не так, почему в вашем случае, просто так всегда происходит.

Эти проблемы легче обнаружить с помощью интерактивногоотладчик с точками останова и переменной проверки.Это позволяет вам заглянуть в программу во время ее выполнения, и вы можете увидеть в реальном времени, что происходит с данными.Однако у тебя не всегда так.Другой альтернативой является установка точек останова самостоятельно (die) и выполнение вывода самостоятельно (echo, var_dump и т. Д.).

3.XML может быть изменен браузером.

Я уже писал об этом в начале и между ними.В основном, если вы не видите исходный код как есть, но искалечены браузером, вы просто можете ошибочно предположить причину ошибки.Это похоже на использование неправильных очков и просто мешает вам отследить все в первую очередь.Так что знайте свои инструменты.


Вещи не всегда легко обнаружить.Вы должны смотреть в правильную область в первую очередь, и вы должны последовательно отслеживать вещи.Могут быть разные причины, по которым все происходит, если программное обеспечение более сложное, например Wordpress.

0 голосов
/ 24 июля 2011

Попробуйте использовать html_entity_decode() или htmlspecialchars_decode(). Либо должно работать для этого случая.

http://www.php.net/manual/en/function.html-entity-decode.php http://www.php.net/manual/en/function.htmlspecialchars-decode.php

Кодировать его специально:

$xml .= '<item number="'.$i.'">
                <sku>'.$this->get_product_sku($key, $value).'</sku>
                <description>
                    &lt;![CDATA[
                    '.get_the_title($value['prodid']).'
                    ]]&gt;
                </description> 
                <qty>'.$value['quantity'].'</qty>
                <price>'.$value['price'].'</price> 
                <extended>'.$value['quantity']*$value['price'].'</extended>
            </item>';

Затем расшифруйте его на дисплее:

echo html_entity_decode($xml);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...