返回XML的自定义终结点

时间:2020-11-10 作者:pmj

我需要创建一个端点,该端点在调用时返回一个包含存储产品的XML。我已经生成了XML,但我不知道如何让端点以XML格式返回它,因为现在它以JSON格式返回它,而作为XML,它不能很好地返回它。

这是我的代码:

<?php

/**
* Plugin Name: example
* Plugin URI: https://www.example.es/
* Description: example
* Version: 1.0
* Author: example
* Author URI: https://www.example.es/
*/

function smg_feed() {
   $args = array( \'post_status\' => \'publish\', numberposts => -1 );
   $products = wc_get_products($args);

   $xml_header = \'<?xml version="1.0" encoding="UTF-8"?><Document></Document>\';
   $xml = new SimpleXMLElement($xml_header);

   foreach($products as $product) {
       $data = $product->get_data();
       $sku = $data[\'sku\'];
       $categoriasNombres = array();
       $subcategoriasNombres = array();
       foreach( wp_get_post_terms( $data[\'id\'], \'product_cat\' ) as $term ){
           if( $term ){
               if ($term->name == \'XXXX\' || $term->name == \'YYYY\') {
                   array_push($categoriasNombres, $term->name);
               } else {
                array_push($subcategoriasNombres, $term->name);
               }
           }
       }
       $categoriasNombres = implode(\',\', $categoriasNombres);
       $subcategoriasNombres = implode(\',\', $subcategoriasNombres);
       $propiedadesNombres = array();
       foreach( wp_get_post_terms( $data[\'id\'], \'product_tag\' ) as $term ){
           if( $term ){
               array_push($propiedadesNombres, $term->name);
           }
       }
       $propiedadesNombres = implode(\',\', $propiedadesNombres);
       $nombre = $data[\'name\'];
       $formatosNombres = array();
       foreach( wp_get_post_terms( $data[\'id\'], \'pa_formato\' ) as $term ){
           if( $term ){
               array_push($formatosNombres, $term->name);
           }
       }
       $formatosNombres = implode(\',\', $formatosNombres);
       $metaData = $data[\'meta_data\'];

       foreach($metaData as $item) {
           if ($item->key == \'_role_based_price\') {
               $obj = $item->value;
               $precio = $obj[\'api1\'][\'regular_price\'];
               $precioEspecial = $obj[\'api2\'][\'regular_price\'];
           }
       }

       $row = $xml->addChild(\'row\');
       $row->addChild(\'sku\', $sku);
       $row->addChild(\'categorias\', $categoriasNombres);

       $row->addChild(\'subcategorias\', $subcategoriasNombres);
       $row->addChild(\'propiedades\', $propiedadesNombres);
       $row->addChild(\'nombre\', $nombre);
       // $row->addChild(\'imagen\', );

       $row->addChild(\'formatos\', $formatosNombres);
       $row->addChild(\'precio\', $data[\'regular_price\']);
       $row->addChild(\'precio_especial\', $precioEspecial);
   }

   $output = $xml->asXML();

   return $output;
}

add_action(\'rest_api_init\', function() {

   register_rest_route(\'smg/v1\', \'feed\', [
       \'methods\' => \'GET\',
       \'callback\' => \'smg_feed\',
   ]);

});
但当我调用端点时,它返回的是:

"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>\\n
<Document>
<row>
<sku\\/>
<categorias>Nutrici\\u00f3n<\\/categorias>
<subcategorias>Nutridefense Plus<\\/subcategorias>
<propiedades>todo<\\/propiedades>
<nombre>NutriDefense plus<\\/nombre>
<formatos\\/>
<precio>29,90<\\/precio>
<precio_especial>26,52<\\/precio_especial>
<\\/row>
<\\/Document>\\n"
如何使其以XML格式返回?非常感谢你。

当做

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

默认情况下,端点/回调返回的输出将始终作为JSON编码的字符串发送(并且Content-Type 标题也将是/包含application/json), 因此,不能使用该回调发送XML提要。

但是,您可以使用rest_pre_serve_request hook 如果您想让REST API路由服务于不同类型的内容,如案例中的XML提要。

例如,您可以执行以下操作:

设置回拨(smg_feed()) 返回将在maybe_smg_feed() 以下:(请注意permission_callback 应始终设置,检查the REST API handbook 了解更多详细信息)

function smg_feed( $request ) {
    // ... your code ...
    return \'your XML data\';
}

add_action( \'rest_api_init\', function () {
    register_rest_route( \'smg/v1\', \'feed\', [
        \'methods\'             => \'GET\',
        \'callback\'            => \'smg_feed\', // make sure it returns an XML string
        \'permission_callback\' => \'__return_true\',
    ]);
});

function maybe_smg_feed( $served, $result, $request, $server ) {
    // Bail if the route of the current REST API request is not our custom route.
    if ( \'/smg/v1/feed\' !== $request->get_route() ||
        // Also check that the callback is smg_feed().
        \'smg_feed\' !== $request->get_attributes()[\'callback\'] ) {
        return $served;
    }

    // Send headers.
    $server->send_header( \'Content-Type\', \'text/xml\' );

    // Echo the XML that\'s returned by smg_feed().
    echo $result->get_data();

    // And then exit.
    exit;
}
add_filter( \'rest_pre_serve_request\', \'maybe_smg_feed\', 10, 4 );
或者(正如我在原始答案中提到的),在不使用REST API的情况下(REST API起作用),您可以使用add_feed() 交付XML提要。

(附言:感谢@TimothyJacobs 感谢他的帮助/评论。:)

相关推荐

安装和卸载WP-REST-API插件后API返回空白响应

WordPress/WooCommerce API在我的网站上被破坏:http://example.com/wp-json/wp/v2/posts 和http://example.com/wp-json/wc/v2/products 两者都返回空白响应。运行Python请求response = requests.get(\'http://<mysite>.com/wp-json/wp/v2/posts\', auth=HTTPBasicAuth(*auth)) 给出的响应(在调试器中