Skip to content

Instantly share code, notes, and snippets.

@trey8611
Last active April 17, 2024 17:23
Show Gist options
  • Save trey8611/7b6e79e6610f9d2b06257fb570f05e03 to your computer and use it in GitHub Desktop.
Save trey8611/7b6e79e6610f9d2b06257fb570f05e03 to your computer and use it in GitHub Desktop.
WP All Import - use XPath Query based on Cyrillic attribute value

XPath doesn't allow you to make queries with Cyrillic symbols unless you disable XML pre-processing by adding this code in your child themes functions.php file (or in a plugin like Code Snippets: https://wordpress.org/plugins/code-snippets/):

function wpai_is_xml_preprocess_enabled( $is_enabled ) {
	return false;
}
add_filter( 'is_xml_preprocess_enabled', 'wpai_is_xml_preprocess_enabled', 10, 1 );

Once that code is in place, upload your file to an import and queries like this will be possible:

{param[@name="Тип снаряжения"]}
{param[@name="Рулевая колонка"]}
{param[@name="Педали"]}

If you need to keep pre-processing enabled, there are other solutions:

Scenario One

If the values that you're importing do not contain commas, you can use a PHP function to query them.

File Structure

<?xml version="1.0" encoding="utf-8"?>
<products>
	<product>
		<title>Product A</title>
		<sku>PRODA</sku>
		<price>10</price>
		<param name="Рулевая колонка">Example value here</param>
		<param name="Педали">Another value here</param>
	</product>
</products>

Function Code

function map_params( $names, $values, $key ) {
	if ( empty( $key ) ) return ''; 

	$result = '';
	$names_arr = explode( ",", $names );
	$values_arr = explode( ",", $values );

	if ( ! empty( $names_arr ) ) {
		foreach ( $names_arr as $i => $name ) { 
			if ( trim( pmxi_convert_encoding( $name, "UTF-8" ) ) == $key ) {
				$result = isset( $values_arr[ $i ] ) ? trim( $values_arr[ $i ] ) : '';
				break;
			}
		}
	}
	return $result;
}

Usage example

[map_params({param/@name},{param},"Рулевая колонка")]

Scenario Two

If the values contain commas, you'll need to use the wpallimport_xml_row hook to query them.

File Structure

<?xml version="1.0" encoding="utf-8"?>
<products>
	<product>
		<title>Product A</title>
		<sku>PRODA</sku>
		<price>10</price>
		<param name="Рулевая колонка">Example, values, here</param>
		<param name="Педали">More, values, here</param>
	</product>
</products>

Code

function add_param_nodes( $node ) {
    $results = $node->xpath( 'param' );
	  $att = 'name';
    if ( !empty( $results ) ) {
        foreach( $results as $result ) {
			$atts = (string) $result->attributes();
			$atts = trim( pmxi_convert_encoding( $atts, "UTF-8" ) );
			if ( ! empty( $atts ) && $atts == 'Возраст' ) {
				$node->addChild( 'Возраст', $result->__toString() );
			} elseif ( ! empty( $atts ) && $atts == 'Пол' ) {
				$node->addChild( 'Пол', $result->__toString() );
			} elseif ( ! empty( $atts ) && $atts == 'Размер' ) {
				$node->addChild( 'Размер', $result->__toString() );
			}
		}
    }
    return $node;
}
add_filter( 'wpallimport_xml_row', 'add_param_nodes', 10, 1 );

Usage Example

This would add 2 new XPath elements that you can use in your import template:

{Рулеваяколонка[1]}
{Педали[1]}

Alternative Workaround

You could convert the attribute name to HTML entities and query it that way. For example, to query "Рулевая колонка", you'd use the following XPath:

{param[@name="&#x420;&#x443;&#x43B;&#x435;&#x432;&#x430;&#x44F; &#x43A;&#x43E;&#x43B;&#x43E;&#x43D;&#x43A;&#x430;"]}
@mihdan
Copy link

mihdan commented Sep 9, 2019

/**
 * Позволяет получать данные из русских атрибутов {param[@name="Цвет"]}
 */
add_filter( 'is_xml_preprocess_enabled', '__return_false' );

@trey8611
Copy link
Author

trey8611 commented Feb 7, 2020

@mihdan nice catch! I've updated the guide.

@TheLEAX
Copy link

TheLEAX commented Jun 30, 2022

Hi! I would like to inform you about details to your Alternative Workaround

For example: Rozmiar pierścionków

Encoded with https://mothereff.in/html-entities
(Enable option "only encode unsafe and non-ASCII characters")

Rozmiar pierścionków => Rozmiar pier&#x15B;cionk&#xF3;w

!!! PASTING IT IN DESCRIPTION VISUAL TEXT EDITOR BREAKS IT
!!! CHANGE FIRST TO TEXT EDITOR IN WP ALL IMPORT

Different results:

0 {attrs/a/@name} --- Rozmiar pierścionków --- Correct!
1 {attrs/a[@name="Rozmiar pierścionków"]} --- Doesnt work
2 {attrs/a[@name="Rozmiar pier&#x15B;cionk&#xF3;w"]} --- US8 EU17 --- Correct!
3 {attrs/a[@name="Rozmiar pierścionk&oacute;w"]} --- Doesnt work
4 {attrs/a[@name="&#x52;&#x6F;&#x7A;&#x6D;&#x69;&#x61;&#x72;&#x20;&#x70;&#x69;&#x65;&#x72;&#x15B;&#x63;&#x69;&#x6F;&#x6E;&#x6B;&#xF3;&#x77;"]} --- Doesnt work
5 {attrs/a[@name="&#x52;&#x6F;&#x7A;&#x6D;&#x69;&#x61;&#x72; &#x70;&#x69;&#x65;&#x72;&#x15B;&#x63;&#x69;&#x6F;&#x6E;&#x6B;&#xF3;&#x77;"]} --- Doesnt work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment