如何将属性插入所有子节点

时间:2011-03-07 09:36:17

标签: xslt xpath xforms orbeon

请在下面找到我的xform页面。

<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"
    xmlns:exforms="http://www.exforms.org/exf/1-0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xhtml:head>
        <xforms:instance id="instanceData">
            <form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                <fruits>
                    <fruit>
                        <fruit-name>Mango</fruit-name>
                    </fruit>
                    <fruit>
                        <fruit-name>Apple</fruit-name>
                    </fruit>
                    <fruit>
                        <fruit-name>Banana</fruit-name>
                    </fruit>
                </fruits>
            </form>
        </xforms:instance>
    </xhtml:head>
</xhtml:html>

我想在所有水果名称标签中插入属性taste =“good”,如下所示

<fruit-name taste="good">

我尝试了以下方法来实现相同的功能,但它始终只将属性插入第一个水果名称。

<xforms:insert ev:event="xforms-model-construct-done" 
  context="instance('instanceData')/fruits/fruit/fruit-name" 
  origin="xxforms:attribute('taste','good')" />

<xforms:insert ev:event="xforms-model-construct-done" 
  context="instance('instanceData')/fruits/fruit[position() &gt; 0]/fruit-name" 
  origin="xxforms:attribute('taste','good')" />

请建议一种方法将此属性插入到镜头中的所有水果名称节点。 由于水果列表动态,我们需要有一个动态的解决方案。

2 个答案:

答案 0 :(得分:0)

我不知道XForms,但使用XSLT 非常容易完成此任务:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="fruit-name">
  <fruit-name taste="good">
   <xsl:apply-templates select="node()|@*"/>
  </fruit-name>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xforms="http://orbeon.org/oxf/xml/xforms"
  xmlns:exforms="http://www.exforms.org/exf/1-0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xhtml:head>
        <xforms:instance id="instanceData">
            <form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                <fruits>
                    <fruit>
                        <fruit-name>Mango</fruit-name>
                    </fruit>
                    <fruit>
                        <fruit-name>Apple</fruit-name>
                    </fruit>
                    <fruit>
                        <fruit-name>Banana</fruit-name>
                    </fruit>
                </fruits>
            </form>
        </xforms:instance>
    </xhtml:head>
</xhtml:html>

产生了想要的正确结果:

<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:xforms="http://orbeon.org/oxf/xml/xforms"
 xmlns:exforms="http://www.exforms.org/exf/1-0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <xhtml:head>
    <xforms:instance id="instanceData">
      <form xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <fruits>
          <fruit>
            <fruit-name taste="good">Mango</fruit-name>
          </fruit>
          <fruit>
            <fruit-name taste="good">Apple</fruit-name>
          </fruit>
          <fruit>
            <fruit-name taste="good">Banana</fruit-name>
          </fruit>
        </fruits>
      </form>
    </xforms:instance>
  </xhtml:head>
</xhtml:html>

答案 1 :(得分:0)

xxforms:iterate extension attribute是您的朋友。以下将做到这一点。在这种情况下,它甚至比XSLT更简单;)。

<xforms:insert ev:event="xforms-model-construct-done"
               xxforms:iterate="fruits/fruit/fruit-name"
               context="." origin="xxforms:attribute('taste','good')"/>