如何申请两场比赛'父节点和子节点的xsl:template内的规则

时间:2014-06-19 15:33:55

标签: xml xslt xforms

我有以下基本的xml文件:

<structure>
   <part class="Button" id="b1">
        <style>
            <property name="label">Click me!</property>
        </style>
   </part>
</structure>

我正在应用XSL将其转换为带有XForms按钮/最终事件的html布局。我的xsl:模板如下:

<xsl:template match="part[@class='Button']">
    <xforms:trigger>
        <xsl:apply-templates select="@accesskey | @tabindex | @size | @style | @id"/>
        <xforms:label>
            <xsl:value-of select="@label"/>
        </xforms:label>
        <xsl:apply-templates select="@onclick"/>
        <xsl:apply-templates select="*"/>
    </xforms:trigger>
</xsl:template>

理想情况下,我希望xforms:标签采用文字&#34;点击我!&#34;并忽略xml中的样式标记。 所以最终的结果应该是:

<xforms:trigger id="b1">
    <xforms:label>Click me!</xf:label>
</xforms:trigger>

我如何到达那里?提前谢谢!

修改

这是style标记的另一种可能方案的新示例:

<structure>
   <part class="Button" id="b1"/>            
</structure>
<style>
   <property part-name="b1" name='label'>Click me!</property>
</style>

1 个答案:

答案 0 :(得分:1)

要获得结果,您期望您的模板可以更简单:

<xsl:template match="part[@class='Button']">
    <xforms:trigger id="{@id}">
        <xforms:label>
            <xsl:value-of select="style/property[@name='label']"/>
        </xforms:label>
    </xforms:trigger>
</xsl:template>

由于您的模板使用part创建的上下文,因此该上下文到property的路径为style/property。您也可以使用效率较低的路径,例如.//property*/property。使用Attribute Value Templates复制了id

至于你的其他<xsl:apply-templates>,除非你的代码与你在问题中包含的代码大不相同,否则它们似乎毫无意义。最后一个实际上会将所有子元素添加到trigger,这似乎不是您想要的。

UPDATE 为了处理你的第二个场景,我会认为你有一个输入XML,如下面的那个,一些按钮有嵌套样式,另一些按钮引用一个样式。文件中的其他地方:

<?xml version="1.0" encoding="UTF-8"?>
<structure>
    <style>
        <property part-name="b2" name="label">Click me NOT!</property>
        <property part-name="b1" name="label">Click me!</property>
    </style>
    <part class="Button" id="b1"/>
    <part class="Button" id="b3"/>
    <part class="Button" id="b4">
        <style>
            <property name="label">Click me!</property>
        </style>
    </part>
</structure>

要引用<style>块中的属性,我们可以创建一个可通过键选择的地图,即@part-name。当您检索将按钮的ID作为传递的元素时,您将获得相应的property。此行设置了一个名为labels的地图。当使用<property>属性的值调用时,它将返回name元素,其label属性的值为part-name

<xsl:key name="labels" match="property[@name='label']" use="@part-name"/>

如果<part>地图中存在一个密钥等于其Button的元素,则此模板将生成labels @id元素所需的代码。然后它将检索该元素并使用其值:

<xsl:template match="part[@class='Button'][key('labels', @id)]">
    <xforms:trigger id="{@id}">
        <xforms:label>
            <xsl:value-of select="key('labels', @id)"/>
        </xforms:label>
    </xforms:trigger>
</xsl:template>

这是完整的样式表,它处理可能包含两种方案的实例(例如上面列出的方案):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xforms="http://www.w3.org/2002/xforms" version="1.0">
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <!-- Map containing all property[@name='label'] using by their @part-name as key -->
    <xsl:key name="labels" match="property[@name='label']" use="@part-name"/>

    <xsl:template match="/">
        <root>
            <xsl:apply-templates select="structure/part"/>
        </root>
    </xsl:template>

    <!-- All <part> elements that do not match the other two templates -->
    <xsl:template match="part"/>

    <!-- Buttons which have an @id corresponding to a style/property @part-name -->
    <xsl:template match="part[@class='Button'][key('labels', @id)]">
        <xforms:trigger id="{@id}">
            <xforms:label>
                <xsl:value-of select="key('labels', @id)"/>
            </xforms:label>
        </xforms:trigger>
    </xsl:template>

    <!-- Buttons which have a nested style/property with @name=label -->
    <xsl:template match="part[@class='Button'][style/property[@name='label']]">
        <xforms:trigger id="{@id}">
            <xforms:label>
                <xsl:value-of select="style/property[@name='label']"/>
            </xforms:label>
        </xforms:trigger>
    </xsl:template>

</xsl:stylesheet>

使用该数据将生成此结果:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xforms="http://www.w3.org/2002/xforms">
   <xforms:trigger id="b1">
      <xforms:label>Click me!</xforms:label>
   </xforms:trigger>
   <xforms:trigger id="b4">
      <xforms:label>Click me!</xforms:label>
   </xforms:trigger>
</root>

您可以在 XSLT Fiddle

中看到它正常运行并测试结果