如果我有一个简单的XML文档
<albums>
<album name="Napoleon Bonaparte" artist="male" year="1993" genre="rock">
<song title="test" track="1"/>
<song title="test4" track="2"/>
<song title="test6" track="3"/>
</album>
<album name="Cleopatra" artist="female" year="1993" genre="jazz">
<song title="test1" track="1"/>
<song title="test2" track="2"/>
<song title="test3" track="3"/>
</album>
</albums>
和
的模板<box id="albumList" orient="vertical" datasources="list.xml" ref="*" querytype="xml">
<template>
<query expr="*" />
<action>
<box uri="?" align="left" class="album" orient="vertical">
<box flex="1">
<description class="albumName" value="?name"/>
<label class="albumArtist" value="?artist"/>
</box>
<listbox class="songlist" align="left" collapsed="true">
<listitem uri="?" label="?title"/>
</listbox>
</box>
</action>
</template>
</box>
如何让<listbox>
元素正确显示专辑名称下方每首歌曲的标题?相册名称/艺术家显示正常,但我无法弄清楚如何构建XML查询以定位song
的{{1}}个孩子
答案 0 :(得分:2)
这是一个非常棘手的问题,谢谢你的提问。 Using recursive templates文档提供了一些线索,但似乎缺少一个重要的部分。以下是最终的作用:
<vbox id="albumList" datasources="list.xml" ref="*" querytype="xml">
<template>
<query expr="album|song">
<assign var="?type" expr="local-name(.)"/>
</query>
<rule>
<where subject="?type" rel="equals" value="album"/>
<action>
<vbox uri="?" align="left" class="album">
<vbox flex="1">
<description class="albumName" value="?name"/>
<label class="albumArtist" value="?artist"/>
</vbox>
<listbox uri="?" class="songlist" align="left"/>
</vbox>
</action>
</rule>
<rule parent="listbox">
<where subject="?type" rel="equals" value="song"/>
<action>
<listitem uri="?" label="?title"/>
</action>
</rule>
</template>
</vbox>
根据文档的建议,这会将XML标记名称分配给?type
变量,并使用它为album
和song
标记生成不同的内容(通过<rule>
和<where>
)。请注意uri="?"
标记上的<listbox>
,它将该标记指定为需要插入生成的子标记内容的点。但模板引擎还会将子标记的内容直接插入到父标记的内容中 - 这可以通过parent="listbox"
对歌曲规则的限制来防止。我将查询表达式更改为album|song
以确保立即忽略其他标记,但这不是必需的。
附注:通常不使用<box>
标记。 <hbox>
和<vbox>
代码是首选,因为它们不需要您单独指定内容方向。