Re: Generic template question

Daniel Dekany <[email protected]>
Newsgroups gmane.comp.web.freemarker.user
Message-ID <[email protected]>
Thursday, February 19, 2009, 9:56:49 PM, Kirill wrote:
> Hi Daniel,
>
> Thanks for your input. I tried that and got no luck...
>
> So, given the sample XML:
> <root>
> <item attr1="123" attr2="345">itemText</item>
> </root>
>
> and taking into consideration scenario, that we don't know for sure
> how many <item>'s are there, and attributes in each item as well -
> what the template has to look like?
>
> This is what I got so far:
>
> <#ftl>
>
> <#recurse doc>
>
> <#macro @element>
>     <#if .node?children?has_content>
>     ${.node.@@start_tag}
>     </#if>
>
>     <#if !.node?children?has_content>

(That could be done better with <#else>.)

>     <${.node?node_name}/>
>     </#if>


>     <#if .node?children?size = 1>
>         ${r"${"}${.node?parent?node_name}.${.node?node_name}${r"}"}
>     </#if>
>
>     <#if .node?children?size &gt; 0>
>     <#recurse>
>     </#if>
>
>     <#if .node?children?has_content>
>     ${.node.@@end_tag}
>     </#if>
> </#macro>
>
> Can I just specify a macro for all attributes?
> Something like:
> <#macro @attrName>
> <#list @element["@*"] as attributes>
> ${attributes?node_name}
> </#list>
> </#macro>

Yes, you can. The key problem is problem is, #recurse doesn't attempt
to visit attribute nodes (because W3C DOM doesn't treat attributes as
children). But you can solve that like this:

  <#macro recurseAttributes>
    <#list .node["@*"] as att>
      <#visit att>
    </#list>
  </#macro>

And then, you can do something like:

  <#macro @element>
    ELEM: I'm the ${.node?node_name} element.
          I'm belonging the ${.node?node_namespace} namespace.
    <@recurseAttributes/>  <#-- Visit attributes only -->
    <#recurse>             <#-- Visit all other kind of nodes -->
  </#macro>

  <#macro @attribute>
    ATT: I'm the ${.node?node_name} attribute
         of an ${.node?parent?node_name} element.
         I'm belonging to the ${.node?node_namespace!'void'} namespace.
         My value is: ${.node}
  </#macro>

> (Also, that <#if> test you mentioned redundant has to be there,
> otherwise there is no recursion to child nodes, for some reason...).

No way. That #if will always execute #recurse, except if there is no
child node, and in that case it won't do anything, no mater if the #if
is there.

> Thanks again,
> Kirill
>
>
> On Thu, Feb 19, 2009 at 2:29 AM, fm <[email protected]> wrote:
> Hello Kirill,
>
> Thursday, February 19, 2009, 5:14:32 AM, you wrote:
>
> [snip]
>> <#macro @element>
>>         ${.node.@@start_tag}
>>         <#if .node?children?size = 1>
>>                 ${r"${"}${.node.@@qname}${r"}"}
>>         </#if>
>>         <#if .node?children?size &gt; 0>
>>                 <#recurse>
>>         </#if>
> [snip]
>
> (I suppose #recurse just does nothing if there are no children, so
> that #if is redundant there.)
>
> [snip]
>> The question is - how do I get to the bound namespaces and attributes?
>
> whateverNode?node_namespace
>
>> For example, if I get a tag like: <root attribute="value"/>, how do I
>> get to "attribute" and its' "value"?
>
> If you know the attribute name, you write someElement.@someAttName.
> If you don't know the attribute names you can list them with
> someElement["@*"] (or someElement.@@ -- same thing, just not
> immediately obvious for those who know XPath). Then if you have the
> attribute name in variable, you can write someElement["@" + attName].
>
>> Or, if I get a tag like <root xmlns:namespace="HTTP://foo"/>, how do I
>> retrieve the "xmlns:namespace" part (and its' value)?
>
> You don't usually. Unfortunately (as far as I know...) the XML infoset
> W3C rec. doesn't state that xmlns attributes are not part of the
> infoset, but for practical purposes they are irrelevant when
> processing XML. You can query the namespace of the node belongs to
> with ?node_namespace, for *each* node, regardless of the location of
> the xmlns attributes.
>
>> Thanks for all the input.
>
>> - Kirill
>
>> ------------------------------------------------------------------------------
>> Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
>> -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
>> -Strategies to boost innovation and cut costs with open source participation
>> -Receive a $600 discount off the registration fee with the source code: SFAD
>> http://p.sf.net/sfu/XcvMzF8H
>> _______________________________________________
>> FreeMarker-user mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/freemarker-user
>
>
>>  _____________ NOD32 3680 (20081210) Információ _____________
>
>> Az üzenetet a NOD32 antivirus system megvizsgálta.
>> http://www.nod32.hu
>
>
>
>
> --
> Best regards,
>  fm                            mailto:[email protected]
>
>
>

-- 
Best regards,
 Daniel Dekany


------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.