[stringtemplate-interest] Problems with List and Hashes revisited
Dreyer Ulf (CR/APA3)
Ulf.Dreyer at de.bosch.com
Mon May 29 06:55:46 PDT 2006
Hello all!
I hope, I'm not getting on your nerves yet but I'd like to
diskuss my issue with ST# some more.
First let me quote Jeremy (who put it so nicely)
"At the end of the day I absolutely love ST#"
But at times it is driving me up the wall!
(Or maybe it is my ignorance about some finer points
of ST#)
I am trying to read (more or less arbitrary) xml data
from disc and feed them to a 'root template' which
in turn calls other user-defined subtemplates.
As my mail is rather long (again) the problem in short:
I think (not entirely sure) ST# somtimes treats single
values (which are aggregates (hashmap)) as lists.
(It enumerates my hash)
"Sometimes" meaning whenever I call a subtemplate
that is defined without formal parameters OR
I call a subtemplate (with or without formal parameters defined)
in the <single value>:subtemplate() syntax.
??
What do I have to do so that ST# can deal with
<DataStruct>:subtemplate()
whether DataStruct is a single value (or aggregate)
or a List?
??
Putting another pair of brackets "()" around the argument
does'nt work because
a) it is not universal (if the argument CAN be multi-valued)
b) it casts the argument to string (which is bad for aggregate values)
First some real code so you have a chance to
understand, what I am talking about:
(sorry for the lengthy text but I hope it helps)
Sample xml-file:
<?xml version="1.0"?>
<root>
<DataBlock1>
<DataA>1_DataA</DataA>
<DataB>1_DataB</DataB>
<DataC>
<SubC1>1_SubC1Content1</SubC1>
<SubC1>1_SubC1Content2</SubC1>
<SubC2>1_SubC2Content</SubC2>
</DataC>
</DataBlock1>
<DataBlock1>
<DataA>2_DataA</DataA>
<DataB>2_DataB</DataB>
<DataC>
<SubC1>2_SubC1Content1</SubC1>
<SubC1>2_SubC1Content2</SubC1>
<SubC2>2_SubC2Content</SubC2>
</DataC>
</DataBlock1>
<DataBlock2>
<ItemB>ItemBContent</ItemB>
</DataBlock2>
</root>
-------------------------------------------------------------
Sample TemplateGroup:
group behaviourDemo;
subsubTemplate(Data) ::= <<
Input is : $Data$
SubC1 is '$Data.SubC1$'
SubC2 is '$Data.SubC2$'
>>
subsubTemplateB() ::= <<
Input is : $it$
SubC1 is '$it.SubC1$'
SubC2 is '$it.SubC2$'
>>
subTemplate() ::= <<
------------------------------------------------------
A=$it.DataA$
B=$it.DataB$
// both blocks SHOULD return the same:
subsubTemplate(it.DataC):
$subsubTemplate(it.DataC)$
----------------------------
it.DataC:subsubTemplate():
$it.DataC:subsubTemplate()$
------------------------------------------------------
>>
rootTemplate(DataBlock1,DataBlock2) ::= <<
BEGIN (rootTemplate)
Applying the subtemplate to DataBlock1:
$DataBlock1:subTemplate()$
======================================================
Accessing part of DataBlock1 directly (multi-valued):
DataBlock1.DataA = $DataBlock1.DataA$
Accessing part of DataBlock2 directly (single-valued):
DataBlock2.ItemB = $DataBlock2.ItemB$
END (rootTemplate)
>>
To archive my goal I have written a data-structure consisting
of ArrayLists and Hashmaps (alternating).
A hash being the root and containing Lists(of hashes) for multi-valued
attributes or attributes (Strings) for single-values.
DataBlock2.ItemB = $DataBlock2.ItemB$ from the rootTemplate always
works. (good!)
DataBlock1.DataA = $DataBlock1.DataA$ does not normally work because the
"answer"
would be multi-valued.
I got this to work too by writing a List which implements a this[string]
accessor that
iterates over the list and constructs a new list from the matching
attributes of the
hashmaps in the list. (Essentially skipping one "layer" of the data
structure)
@Kunle: This is how I solved the last problem I mailed you about.
In the example my list implementation returns [1_DataA,2_DataA] if
called as
myList_DataBlock1["DataA"] (Not necessarily stings but whatever the
hashes contain at key "DataA").
One last problem which I feel is related to the " question regarding
specialcasingof IList"
previously on the mailinlist.
The call to the subsubTemplate!
As you see from the code I have given two implementations.
The one with the named parameter works IF (and only if) I call it
$subsubTemplate(it.DataC)$
My preferred version of
$it.DataC:subsubTemplate()$
does NOT work.
Neither does the subsubTemplateB in any version
>From the output below one can see that $it.DataC:subsubTemplate()$
gives a list to subsubTemplate() when it SHOULD be a Hash containing
a list (of 2 items) and a single value.
Any idea why this is the case?
My implementations of of List and Hash:
public class AttributeList : ArrayList,Iattribute
public class AttributeHash : IDictionary, IAttribute
(Iattribute defines object this[object key] but it
does not work without this hack in AttributeList either)
------------------------------------------------------
BEGIN (rootTemplate)
Applying the subtemplate to DataBlock1:
------------------------------------------------------
A=1_DataA
B=1_DataB
// both blocks SHOULD return the same:
subsubTemplate(it.DataC):
Input is : 1_SubC1Content11_SubC1Content21_SubC2Content
SubC1 is '1_SubC1Content11_SubC1Content2'
SubC2 is '1_SubC2Content'
----------------------------
it.DataC:subsubTemplate():
Input is : 1_SubC1Content11_SubC1Content2
SubC1 is ''
SubC2 is ''
Input is : 1_SubC2Content
SubC1 is ''
SubC2 is ''
------------------------------------------------------
------------------------------------------------------
A=2_DataA
B=2_DataB
// both blocks SHOULD return the same:
subsubTemplate(it.DataC):
Input is : 2_SubC1Content12_SubC1Content22_SubC2Content
SubC1 is '2_SubC1Content12_SubC1Content2'
SubC2 is '2_SubC2Content'
----------------------------
it.DataC:subsubTemplate():
Input is : 2_SubC1Content12_SubC1Content2
SubC1 is ''
SubC2 is ''
Input is : 2_SubC2Content
SubC1 is ''
SubC2 is ''
------------------------------------------------------
======================================================
Accessing part of DataBlock1 directly (multi-valued):
DataBlock1.DataA = 1_DataA2_DataA
Accessing part of DataBlock2 directly (single-valued):
DataBlock2.ItemB = ItemBContent
END (rootTemplate)
-------------------------------------------------------
Before that I get some errors along the lines of
Can't get property SubC1 via C# string indexer from
SomeNameSpace.AttributeList instance
[...]
Class System.String has no such attribute: SubC2 in template context
[rootTemplate subTemplate subsubTemplate]
Where SomeNameSpace.AttributeList is my Listimplementations which
supports attribute lookup from
the listed hashes.
I don't understand why ST# tries to get the attribute from a string.
Has anyone similar problems or any idea how I can get the expected
results from ST?
@ Terrence or Kunle: how does the Attribute-Lookup work exactly?
Thanks for reading this far!
Ulf
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org:8080/pipermail/stringtemplate-interest/attachments/20060529/7cf6133d/attachment-0001.html
More information about the stringtemplate-interest
mailing list