@@ -196,44 +196,168 @@ Array Node Options
196196Before defining the children of an array node, you can provide options like:
197197
198198``useAttributeAsKey() ``
199- Provide the name of a child node, whose value should be used as the
200- key in the resulting array.
199+ Provide the name of a child node, whose value should be used as the key in
200+ the resulting array. This method also defines the way config array keys are
201+ treated, as explained in the following example.
201202``requiresAtLeastOneElement() ``
202203 There should be at least one element in the array (works only when
203204 ``isRequired() `` is also called).
204205``addDefaultsIfNotSet() ``
205206 If any child nodes have default values, use them if explicit values
206207 haven't been provided.
208+ ``normalizeKeys(false) ``
209+ If called (with ``false ``), keys with dashes are *not * normalized to underscores.
210+ It is recommended to use this with prototype nodes where the user will define
211+ a key-value map, to avoid an unnecessary transformation.
207212
208- An example of this ::
213+ A basic prototyped array configuration can be defined as follows ::
209214
210- $rootNode
215+ $node
216+ ->fixXmlConfig('driver')
211217 ->children()
212- ->arrayNode('parameters')
213- ->isRequired()
214- ->requiresAtLeastOneElement()
215- ->useAttributeAsKey('name')
218+ ->arrayNode('drivers')
219+ ->prototype('scalar')->end()
220+ ->end()
221+ ->end()
222+ ;
223+
224+ When using the following YAML configuration:
225+
226+ .. code-block :: yaml
227+
228+ drivers : ['mysql', 'sqlite']
229+
230+ Or the following XML configuration:
231+
232+ .. code-block :: xml
233+
234+ <driver >msyql</driver >
235+ <driver >sqlite</driver >
236+
237+ The processed configuration is::
238+
239+ Array(
240+ [0] => 'mysql'
241+ [1] => 'sqlite'
242+ )
243+
244+ A more complex example would be to define a prototyped array with children::
245+
246+ $node
247+ ->fixXmlConfig('connection')
248+ ->children()
249+ ->arrayNode('connections')
216250 ->prototype('array')
217251 ->children()
218- ->scalarNode('value')->isRequired()->end()
252+ ->scalarNode('table')->end()
253+ ->scalarNode('user')->end()
254+ ->scalarNode('password')->end()
219255 ->end()
220256 ->end()
221257 ->end()
222258 ->end()
223259 ;
224260
225- In YAML, the configuration might look like this :
261+ When using the following YAML configuration :
226262
227263.. code-block :: yaml
228264
229- database :
230- parameters :
231- param1 : { value: param1val }
265+ connections :
266+ - { table: symfony, user: root, password: ~ }
267+ - { table: foo, user: root, password: pa$$ }
268+
269+ Or the following XML configuration:
270+
271+ .. code-block :: xml
272+
273+ <connection table =" symfony" user =" root" password =" null" />
274+ <connection table =" foo" user =" root" password =" pa$$" />
275+
276+ The processed configuration is::
277+
278+ Array(
279+ [0] => Array(
280+ [table] => 'symfony'
281+ [user] => 'root'
282+ [password] => null
283+ )
284+ [1] => Array(
285+ [table] => 'foo'
286+ [user] => 'root'
287+ [password] => 'pa$$'
288+ )
289+ )
290+
291+ The previous output matches the expected result. However, given the configuration
292+ tree, when using the following YAML configuration:
293+
294+ .. code-block :: yaml
295+
296+ connections :
297+ sf_connection :
298+ table : symfony
299+ user : root
300+ password : ~
301+ default :
302+ table : foo
303+ user : root
304+ password : pa$$
305+
306+ The output configuration will be exactly the same as before. In other words, the
307+ ``sf_connection `` and ``default `` configuration keys are lost. The reason is that
308+ the Symfony Config component treats arrays as lists by default.
309+
310+ .. note ::
311+
312+ As of writing this, there is an inconsistency: if only one file provides the
313+ configuration in question, the keys (i.e. ``sf_connection `` and ``default ``)
314+ are *not * lost. But if more than one file provides the configuration, the keys
315+ are lost as described above.
316+
317+ In order to maintain the array keys use the ``useAttributeAsKey() `` method::
318+
319+ $node
320+ ->fixXmlConfig('connection')
321+ ->children()
322+ ->arrayNode('connections')
323+ ->prototype('array')
324+ ->useAttributeAsKey('name')
325+ ->children()
326+ ->scalarNode('table')->end()
327+ ->scalarNode('user')->end()
328+ ->scalarNode('password')->end()
329+ ->end()
330+ ->end()
331+ ->end()
332+ ->end()
333+ ;
334+
335+ The argument of this method (``name `` in the example above) defines the name of
336+ the attribute added to each XML node to differentiate them. Now you can use the
337+ same YAML configuration showed before or the following XML configuration:
338+
339+ .. code-block :: xml
232340
233- In XML, each ``parameters `` node would have a ``name `` attribute (along
234- with ``value ``), which would be removed and used as the key for that element
235- in the final array. The ``useAttributeAsKey `` is useful for normalizing
236- how arrays are specified between different formats like XML and YAML.
341+ <connection name =" sf_connection"
342+ table =" symfony" user =" root" password =" null" />
343+ <connection name =" default"
344+ table =" foo" user =" root" password =" pa$$" />
345+
346+ In both cases, the processed configuration maintains the ``sf_connection `` and
347+ ``default `` keys::
348+
349+ Array(
350+ [sf_connection] => Array(
351+ [table] => 'symfony'
352+ [user] => 'root'
353+ [password] => null
354+ )
355+ [default] => Array(
356+ [table] => 'foo'
357+ [user] => 'root'
358+ [password] => 'pa$$'
359+ )
360+ )
237361
238362Default and Required Values
239363---------------------------
0 commit comments