From 21f9a01302a03d68b23f73dca5fc3a69a68f82b4 Mon Sep 17 00:00:00 2001
From: SebCorbin <seb.corbin@gmail.com>
Date: Wed, 29 Jul 2015 13:56:26 +0200
Subject: [PATCH 1/2] Allow for a XPath subquery that is not an attribute

---
 plugins/sources/xml.inc | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/plugins/sources/xml.inc b/plugins/sources/xml.inc
index ede9f82..6a3984e 100644
--- a/plugins/sources/xml.inc
+++ b/plugins/sources/xml.inc
@@ -913,6 +913,13 @@ class MigrateXMLReader implements Iterator {
   public $elementQuery;
 
   /**
+   * Xpath string used to test if the element matches the subquery.
+   *
+   * @var string
+   */
+  public $elementXpath = NULL;
+
+  /**
    * Xpath query string used to retrieve the primary key value from each
    * element.
    *
@@ -968,14 +975,18 @@ class MigrateXMLReader implements Iterator {
     preg_match_all('|^/([^\[]+)(.*)$|', $element_query, $matches);
     $element_path = $matches[1][0];
     $this->elementsToMatch = explode('/', $element_path);
-    $attribute_query = $matches[2][0];
-    if ($attribute_query) {
+    $sub_query = $matches[2][0];
+    if ($sub_query) {
       // Matches [@attribute="value"] (with either single- or double-quotes).
-      preg_match_all('|^\[@([^=]+)=[\'"](.*)[\'"]\]$|', $attribute_query,
-                     $matches);
-      $this->attributeName = $matches[1][0];
-      $this->attributeValue = $matches[2][0];
-    }
+      if (preg_match_all('|^\[@([^=]+)=[\'"](.*)[\'"]\]$|', $sub_query,
+        $matches)) {
+        $this->attributeName = $matches[1][0];
+        $this->attributeValue = $matches[2][0];
+      }
+      else {
+        // If not an attribute, then xpath will be applied to the element
+        $this->elementXpath = $sub_query;
+      }
 
     // If the element path contains any colons, it must be specifying
     // namespaces, so we need to compare using the prefixed element
@@ -1042,6 +1053,10 @@ class MigrateXMLReader implements Iterator {
               $node = $dom->importNode($node, TRUE);
               $dom->appendChild($node);
               $this->currentElement = simplexml_import_dom($node);
+              // Test the element againt its Xpath (if set)
+              if ($this->elementXpath && !$this->currentElement->xpath('/*' . $this->elementXpath)) {
+                continue;
+              }
               $idnode = $this->currentElement->xpath($this->idQuery);
               if (is_array($idnode)) {
                 $this->currentId = (string) reset($idnode);

From ed070f9fac1f179916bd5b8c09258290bc1d9c07 Mon Sep 17 00:00:00 2001
From: SebCorbin <seb.corbin@gmail.com>
Date: Wed, 29 Jul 2015 14:17:38 +0200
Subject: [PATCH 2/2] Update xml.inc

---
 plugins/sources/xml.inc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/plugins/sources/xml.inc b/plugins/sources/xml.inc
index 6a3984e..d81f7e0 100644
--- a/plugins/sources/xml.inc
+++ b/plugins/sources/xml.inc
@@ -987,6 +987,7 @@ class MigrateXMLReader implements Iterator {
         // If not an attribute, then xpath will be applied to the element
         $this->elementXpath = $sub_query;
       }
+    }
 
     // If the element path contains any colons, it must be specifying
     // namespaces, so we need to compare using the prefixed element
