3 ms·
There's absolutely no way that this (copied from https://github.com/akeeba/fof/wiki/The-XML-configuration-file https://github.com/akeeba/fof/wiki/The-XML-config
by eadmund 8y ago
There's absolutely no way that this (copied from https://github.com/akeeba/fof/wiki/The-XML-configuration-file https://github.com/akeeba/fof/wiki/The-XML-configuration-fil...):
<?xml version="1.0" encoding="UTF-8"?>
<fof>
<!-- Common settings -->
<common>
<!-- Container configuration -->
<container>
<option name="componentNamespace"><![CDATA[MyCompany\MyApplication]]></option>
</container>
<!-- Dispatcher configuration -->
<dispatcher>
<option name="defaultView">items</option>
</dispatcher>
<!-- Transparent authentication configuration -->
<authentication>
<option name="totpKey">ABCD123456</option>
<option name="authenticationMethods">HTTPBasicAuth_TOTP,QueryString_TOTP</option>
</authentication>
<!-- Model configuration. One tag for each Model. -->
<model name="orders">
<!-- Model configuration -->
<config>
<option name="tbl"><![CDATA[#__fakeapp_orders]]></option>
</config>
<!-- Field aliasing. One tag per aliased field -->
<field name="enabled">published</field>
<!-- Relation setup. One tag per relation -->
<relation type="hasMany" name="items" />
<relation type="belongsToMany"
name="transactions"
localKey="foobar_order_id"
foreignKey="foobar_transaction_id"
pivotLocalKey="foobar_order_id"
pivotForeignKey="foobar_transaction_id"
pivotTable="#__foobar_orders_transactions" />
<relation type="belongsTo" name="client" foreignModelClass="Users@com_fakeapp" />
<!-- Behaviour setup. Use merge="1" to merge with already defined behaviours. -->
<behaviors merge="1">foo,bar,baz</behaviors>
</model>
<!-- Controller, View and Toolbar setup. One tag per view. -->
<view name="item">
<!-- Controller task aliasing -->
<taskmap>
<task name="list">browse</task>
</taskmap>
<!-- Controller ACL mapping -->
<acl>
<task name="dosomething" />
<task name="somethingelse">core.manage</task>
</acl>
<!-- Controller and View options -->
<config>
<option name="autoRouting">3</option>
</config>
<!-- Toolbar configuration -->
<toolbar title="COM_FOOBAR_TOOLBAR_ITEM" task="edit">
<button type="save" />
<button type="saveclose" />
<button type="savenew" />
<button type="cancel" />
</toolbar>
</view>
</common>
<!-- Component backend options -->
<backend>
<!-- The same options as Common Settings apply here, too -->
</backend>
<!-- Component frontend options -->
<frontend>
<!-- The same options as Common Settings apply here, too -->
</frontend>
</fof>
is at all preferable to this:
(fof
(common
(container (component-namespace "MyCompany\\MyApplication"))
(dispatcher (default-view items))
(authentication
(totp-key ABCD123456)
(authentication-methods (http-basic-auth-totp query-string-totp)))
(model orders
(config (tbl "#__fakeapp_orders"))
;; Field aliasing. One tag per aliased field
(field enabled published)
;; Relation setup. One tag per relation
(relation items (type has-many))
(relation transaction (type belongs-to-many)
(local-key "foobar_order_id")
(foreign-key "foobar_transaction_id")
(pivot-local-key "foobar_order_id")
(pivot-foreign-key "foobar_transaction_id")
pivot-table "#__foobar_orders_transactions")
(relation client (type belongs-to)
(foreign-model-class "Users@com_fakeapp"))
;; Behaviour setup. Use merge="1" to merge with already defined behaviours.
(behaviors (merge 1) (foo bar baz)))
;; Controller, View and Toolbar setup. One tag per view.
(view item
(taskmap (list browse))
;; Controller ACL mapping
(acl
(task dosomething)
(task somethingelse core.manage))
;; Controller and View options
(config (auto-routing 3))
;; Toolbar configuration
(toolbar "COM_FOOBAR_TOOLBAR_ITEM"
(task edit)
(button save)
(button saveclose)
(button savenew)
(button cancel))))
(backend)
(frontend))
There's just no way.
- macspoofing 8y agoYou changed the model when you adapted the xml to lisp. You decided that some tags are unnecessary, dropped some attributes and assumed others are merely different types of child nodes - and now your sample doesn't actually have the same semantic meaning as the XML example. You also removed some comments. Was all this done to emphasis how much cleaner a lisp alternative would be? If we're playing this game, you can actually simplify the XML configuration file as well. If you attempted to capture everything that the XML does, it would make your lisp sample much more ugly. Anyway, to each his own, but I think XML holds up very well and I do find it more readable and easier to work with that your lisp example. I also never said XML is the best configuration format. For simple configurations a simple property file is by far the best option. For anything complicated (as in your example) XML does a great job. To contrast, JSON would fall flat on its face with this. Not to mention the fact XML parsing is typically part of the standard library of most programming language and most people are familiar with it.
- eadmund 8y ago> You changed the model when you adapted the xml to lisp. That was a conscious decision, because the verbosity of XML prevents clear understanding of a data model, while the cleanness of S-expressions enables a clarity of vision which enables prudent judgement when laying out a data structure. > You also removed some comments. Yes, because they were akin to: // Add 1 & 2, assign to X x = 1 + 2 If you really want an S-expression version of the XML in that example, here is SXML[0]: (*top* (fof (*comment* " Common settings ") (common (*comment* " Container configuration ") (container (option (@ (name "componentNamespace")) "MyCompany\\MyApplication")) (*comment* " Dispatcher configuration ") (dispatcher (option (@ (name "defaultView")) "items")) (*comment* " Transparent authentication configuration ") (authentication (option (@ (name "totpKey")) "ABCD123456") (option (@ (name "authenticationMethods")) "HTTPBasicAuth_TOTP,QueryString_TOTP")) (*comment* " Model configuration. One tag for each Model. ") (model (@ (name "orders")) (*comment* " Model configuration ") (config (option (@ (name "tbl")) "#__fakeapp_orders")) (*comment* " Field aliasing. One tag per aliased field ") (field (@ (name "enabled")) "published") (*comment* " Relation setup. One tag per relation ") (relation (@ (type "hasMany") (name "items"))) (relation (@ (type "belongsToMany") (name "transactions") (localKey "foobar_order_id") (foreignKey "foobar_transaction_id") (pivotLocalKey "foobar_order_id") (pivotForeignKey "foobar_transaction_id") (pivotTable "#__foobar_orders_transactions"))) (relation (@ (type "belongsTo") (name "client") (foreignModelClass "Users@com_fakeapp"))) (*comment* " Behaviour setup. Use merge=\"1\" to merge with already defined behaviours. ") (behaviors (@ (merge "1")) "foo,bar,baz")) (*comment* " Controller, View and Toolbar setup. One tag per view. ") (view (@ (name "item")) (*comment* " Controller task aliasing ") (taskmap (task (@ (name "list")) "browse")) (*comment* " Controller ACL mapping ") (acl (task (@ (name "dosomething"))) (task (@ (name "somethingelse")) "core.manage")) (*comment* " Controller and View options ") (config (option (@ (name "autoRouting")) "3")) (*comment* " Toolbar configuration ") (toolbar (@ (title "COM_FOOBAR_TOOLBAR_ITEM") (task "edit")) (button (@ (type "save"))) (button (@ (type "saveclose"))) (button (@ (type "savenew"))) (button (@ (type "cancel")))))) (*comment* " Component backend options ") (backend (*comment* " The same options as Common Settings apply here, too ")) (*comment* " Component frontend options ") (frontend (*comment* " The same options as Common Settings apply here, too ")))) Which I think is still indubitably and inarguably clearer & cleaner than the XML version. Technically, the XML spec requires whitespace preservation, so really it’s this: (*top* (fof " " (*comment* " Common settings ") " " (common " " (*comment* " Container configuration ") " " (container " " (option (@ (name "componentNamespace")) "MyCompany\\MyApplication") " ") " " (*comment* " Dispatcher configuration ") " " (dispatcher " " (option (@ (name "defaultView")) "items") " ") " " (*comment* " Transparent authentication configuration ") " " (authentication " " (option (@ (name "totpKey")) "ABCD123456") " " (option (@ (name "authenticationMethods")) "HTTPBasicAuth_TOTP,QueryString_TOTP") " ") " " (*comment* " Model configuration. One tag for each Model. ") " " (model (@ (name "orders")) " " (*comment* " Model configuration ") " " (config " " (option (@ (name "tbl")) "#__fakeapp_orders") " ") " " (*comment* " Field aliasing. One tag per aliased field ") " " (field (@ (name "enabled")) "published") " " (*comment* " Relation setup. One tag per relation ") " " (relation (@ (type "hasMany") (name "items"))) " " (relation (@ (type "belongsToMany") (name "transactions") (localKey "foobar_order_id") (foreignKey "foobar_transaction_id") (pivotLocalKey "foobar_order_id") (pivotForeignKey "foobar_transaction_id") (pivotTable "#__foobar_orders_transactions"))) " " (relation (@ (type "belongsTo") (name "client") (foreignModelClass "Users@com_fakeapp"))) " " (*comment* " Behaviour setup. Use merge=\"1\" to merge with already defined behaviours. ") " " (behaviors (@ (merge "1")) "foo,bar,baz") " ") " " (*comment* " Controller, View and Toolbar setup. One tag per view. ") " " (view (@ (name "item")) " " (*comment* " Controller task aliasing ") " " (taskmap " " (task (@ (name "list")) "browse") " ") " " (*comment* " Controller ACL mapping ") " " (acl " " (task (@ (name "dosomething"))) " " (task (@ (name "somethingelse")) "core.manage") " ") " " (*comment* " Controller and View options ") " " (config " " (option (@ (name "autoRouting")) "3") " ") " " (*comment* " Toolbar configuration ") " " (toolbar (@ (title "COM_FOOBAR_TOOLBAR_ITEM") (task "edit")) " " (button (@ (type "save"))) " " (button (@ (type "saveclose"))) " " (button (@ (type "savenew"))) " " (button (@ (type "cancel"))) " ") " ") " ") " " (*comment* " Component backend options ") " " (backend " " (*comment* " The same options as Common Settings apply here, too ") " ") " " (*comment* " Component frontend options ") " " (frontend " " (*comment* " The same options as Common Settings apply here, too ") " ") " ")) But I think that rather proves my point: XML obscures that which should be obvious. (and apologies for these terribly vertical posts — I think that they go a long way towards demonstrating the need for a compact information representation). 0: http://okmij.org/ftp/Scheme/xml.html#SXML-spec http://okmij.org/ftp/Scheme/xml.html#SXML-spec