@@ -24,6 +24,13 @@ class ArrayNodeConfig
24
24
*/
25
25
private $ assocArrays = [];
26
26
27
+ /**
28
+ * Flat array of expanded patterns for matching xpath
29
+ *
30
+ * @var array
31
+ */
32
+ private $ flatAssocArray = [];
33
+
27
34
/**
28
35
* Format: array('/numeric/array/path', ...)
29
36
*
@@ -44,6 +51,7 @@ public function __construct(
44
51
) {
45
52
$ this ->nodePathMatcher = $ nodePathMatcher ;
46
53
$ this ->assocArrays = $ assocArrayAttributes ;
54
+ $ this ->flatAssocArray = $ this ->flattenToAssocKeyAttributes ($ assocArrayAttributes );
47
55
$ this ->numericArrays = $ numericArrays ;
48
56
}
49
57
@@ -71,11 +79,68 @@ public function isNumericArray($nodeXpath)
71
79
*/
72
80
public function getAssocArrayKeyAttribute ($ nodeXpath )
73
81
{
82
+ if (array_key_exists ($ nodeXpath , $ this ->flatAssocArray )) {
83
+ return $ this ->flatAssocArray [$ nodeXpath ];
84
+ }
85
+
74
86
foreach ($ this ->assocArrays as $ pathPattern => $ keyAttribute ) {
75
87
if ($ this ->nodePathMatcher ->match ($ pathPattern , $ nodeXpath )) {
76
88
return $ keyAttribute ;
77
89
}
78
90
}
79
91
return null ;
80
92
}
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
+ }
81
146
}
0 commit comments