Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mbissett/9a22a9b66f9f016d0951d2483ae36014 to your computer and use it in GitHub Desktop.
Save mbissett/9a22a9b66f9f016d0951d2483ae36014 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;"]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment