在XUL文档模板中定位XML子元素

时间:2011-09-20 03:34:24

标签: xml firefox-addon xul

如果我有一个简单的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}}个孩子

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变量,并使用它为albumsong标记生成不同的内容(通过<rule><where>)。请注意uri="?"标记上的<listbox>,它将该标记指定为需要插入生成的子标记内容的点。但模板引擎还会将子标记的内容直接插入到父标记的内容中 - 这可以通过parent="listbox"对歌曲规则的限制来防止。我将查询表达式更改为album|song以确保立即忽略其他标记,但这不是必需的。

附注:通常不使用<box>标记。 <hbox><vbox>代码是首选,因为它们不需要您单独指定内容方向。