@@ -577,16 +577,8 @@ public function filterXPath($xpath)
577
577
$ root ->appendChild ($ document ->importNode ($ node , true ));
578
578
}
579
579
580
- $ domxpath = new \DOMXPath ($ document );
581
- if (preg_match_all ('/(?P<prefix>[a-zA-Z_][a-zA-Z_0-9\-\.]+):[^:]/ ' , $ xpath , $ matches )) {
582
- foreach ($ matches ['prefix ' ] as $ prefix ) {
583
- // ask for one namespace, otherwise we'd get a collection with an item for each node
584
- $ namespaces = $ domxpath ->query (sprintf ('(//namespace::*[name()="%s"])[last()] ' , $ prefix ));
585
- foreach ($ namespaces as $ node ) {
586
- $ domxpath ->registerNamespace ($ node ->prefix , $ node ->nodeValue );
587
- }
588
- }
589
- }
580
+ $ prefixes = $ this ->findNamespacePrefixes ($ xpath );
581
+ $ domxpath = $ this ->createDOMXPath ($ document , $ prefixes );
590
582
591
583
return new static ($ domxpath ->query ($ xpath ), $ this ->uri );
592
584
}
@@ -799,4 +791,43 @@ protected function sibling($node, $siblingDir = 'nextSibling')
799
791
800
792
return $ nodes ;
801
793
}
794
+
795
+ /**
796
+ * @param \DOMDocument $document
797
+ * @param array $prefixes
798
+ *
799
+ * @return \DOMXPath
800
+ *
801
+ * @throws \InvalidArgumentException
802
+ */
803
+ private function createDOMXPath (\DOMDocument $ document , array $ prefixes = array ())
804
+ {
805
+ $ domxpath = new \DOMXPath ($ document );
806
+
807
+ foreach ($ prefixes as $ prefix ) {
808
+ // ask for one namespace, otherwise we'd get a collection with an item for each node
809
+ $ namespaces = $ domxpath ->query (sprintf ('(//namespace::*[name()="%s"])[last()] ' , 'default ' === $ prefix ? '' : $ prefix ));
810
+ if ($ node = $ namespaces ->item (0 )) {
811
+ $ domxpath ->registerNamespace ($ prefix , $ node ->nodeValue );
812
+ } else {
813
+ throw new \InvalidArgumentException (sprintf ('Could not find a namespace for the prefix: "%s" ' , $ prefix ));
814
+ }
815
+ }
816
+
817
+ return $ domxpath ;
818
+ }
819
+
820
+ /**
821
+ * @param $xpath
822
+ *
823
+ * @return array
824
+ */
825
+ private function findNamespacePrefixes ($ xpath )
826
+ {
827
+ if (preg_match_all ('/(?P<prefix>[a-zA-Z_][a-zA-Z_0-9\-\.]+):[^:]/ ' , $ xpath , $ matches )) {
828
+ return array_unique ($ matches ['prefix ' ]);
829
+ }
830
+
831
+ return array ();
832
+ }
802
833
}
0 commit comments