@@ -24,6 +24,13 @@ class ArrayNodeConfig
2424 */
2525 private $ assocArrays = [];
2626
27+ /**
28+ * Flat array of expanded patterns for matching xpath
29+ *
30+ * @var array
31+ */
32+ private $ flatAssocArray = [];
33+
2734 /**
2835 * Format: array('/numeric/array/path', ...)
2936 *
@@ -44,6 +51,7 @@ public function __construct(
4451 ) {
4552 $ this ->nodePathMatcher = $ nodePathMatcher ;
4653 $ this ->assocArrays = $ assocArrayAttributes ;
54+ $ this ->flatAssocArray = $ this ->flattenToAssocKeyAttributes ($ assocArrayAttributes );
4755 $ this ->numericArrays = $ numericArrays ;
4856 }
4957
@@ -71,11 +79,68 @@ public function isNumericArray($nodeXpath)
7179 */
7280 public function getAssocArrayKeyAttribute ($ nodeXpath )
7381 {
82+ if (array_key_exists ($ nodeXpath , $ this ->flatAssocArray )) {
83+ return $ this ->flatAssocArray [$ nodeXpath ];
84+ }
85+
7486 foreach ($ this ->assocArrays as $ pathPattern => $ keyAttribute ) {
7587 if ($ this ->nodePathMatcher ->match ($ pathPattern , $ nodeXpath )) {
7688 return $ keyAttribute ;
7789 }
7890 }
7991 return null ;
8092 }
93+
94+ /**
95+ * Function which takes a patterned list of xpath matchers and flattens to a single level array for
96+ * performance improvement
97+ *
98+ * @param array $assocArrayAttributes
99+ * @return array
100+ */
101+ private function flattenToAssocKeyAttributes ($ assocArrayAttributes )
102+ {
103+ $ finalPatterns = [];
104+ foreach ($ assocArrayAttributes as $ pattern => $ key ) {
105+ $ vars = explode ("/ " , ltrim ($ pattern , "/ " ));
106+ $ stringPatterns = ["" ];
107+ foreach ($ vars as $ var ) {
108+ if (strstr ($ var , "| " )) {
109+ $ repOpen = str_replace ("( " , "" , $ var );
110+ $ repClosed = str_replace (") " , "" , $ repOpen );
111+ $ nestedPatterns = explode ("| " , $ repClosed );
112+ $ stringPatterns = $ this ->mergeStrings ($ stringPatterns , $ nestedPatterns );
113+ continue ;
114+ }
115+
116+ // append this path to all of the paths that currently exist
117+ array_walk ($ stringPatterns , function (&$ value , $ key ) use ($ var ) {
118+ $ value .= "/ " . $ var ;
119+ });
120+ }
121+
122+ $ finalPatterns = array_merge ($ finalPatterns , array_fill_keys ($ stringPatterns , $ key ));
123+ }
124+
125+ return $ finalPatterns ;
126+ }
127+
128+ /**
129+ * Takes 2 arrays and appends all string in the second array to each entry in the first.
130+ *
131+ * @param string[] $parentStrings
132+ * @param string[] $childStrings
133+ * @return array
134+ */
135+ private function mergeStrings ($ parentStrings , $ childStrings )
136+ {
137+ $ result = [];
138+ foreach ($ parentStrings as $ pString ) {
139+ foreach ($ childStrings as $ cString ) {
140+ $ result [] = $ pString . "/ " . $ cString ;
141+ }
142+ }
143+
144+ return $ result ;
145+ }
81146}
0 commit comments