3

我想知道您是否可以在处理过程中访问结果文档。

我问的原因是我正在转换一个输入文档,并且想根据某些条件插入元素,但是当我遍历树并且我即将创建它时,这将不得不发生。

转换后的 xml 看起来与此类似:

<xform>
    <xforms>
        <model>
            <instance>
                <data />
                <data />
            </instance>
        </model>
        <bind />
        <bind />
        <bind />
    </xforms>
</xform>

我打算在转换期间(在上述 xml 被序列化之前)访问<instance>标签并插入其他<data>元素。

注意 输入文档与上面的 xml 不同——上面的 xml 是转换应该产生的。

同样,我想访问<xform>元素并插入其他<bind>节点。

所以最终的文档看起来像这样(假设我添加了 2 个数据节点和 2 个绑定节点):

<xform>
    <xforms>
        <model>
            <instance>
                <data />
                <data />
                <data>new data node</data>
                <data>second new data node</data>
            </instance>
        </model>
        <bind />
        <bind />
        <bind />
        <bind>new bind node</bind>
        <bind>second new bind node</bind>
    </xforms>
</xform>

任何帮助表示赞赏。

4

2 回答 2

3

不,您不能访问结果文档,但是您可以在变量中创建临时树,然后再次处理它们,如果需要使用具有不同模式的模板。所以而不是例如

<xsl:template match="/">
  <xsl:result-document href="example.xml">
<xform>
 <xforms>
  <model>
   <instance>
    <data>
    </data>
   </instance>
  </model>
  <bind />
  <bind />
  <bind />
 </xforms>
</xform>
  </xsl:result-document>
</xsl:template>

您将在变量中创建第一个结果,然后进一步处理它,例如

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

<xsl:template match="/">
  <xsl:variable name="temp1">
<xform>
 <xforms>
  <model>
   <instance>
    <data>
    </data>
   </instance>
  </model>
  <bind />
  <bind />
  <bind />
 </xforms>
</xform>
</xsl:variable>
  <xsl:result-document href="example.xml">
    <xsl:apply-templates select="$temp1/*"/>
  </xsl:result-document>
</xsl:template>

<xsl:template match="instance">
  <xsl:copy>
    <xsl:apply-templates/>
    <data>...</data>
  </xsl:copy>
</xsl:template>

该示例不使用模式,但我经常将它们与变量和不同的处理步骤一起使用,以将每个步骤的模板与其他步骤完全分开。

于 2012-05-22T12:30:10.557 回答
1

是的,这样做的方法是使用多通道处理

<xsl:stylesheet version="2.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()|@*" mode="#default pass2">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*" mode="#current"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/">
  <xsl:variable name="vPass1">
    <xsl:apply-templates/>
  </xsl:variable>

  <xsl:apply-templates select="$vPass1/node()" mode="pass2"/>
 </xsl:template>

 <xsl:template match="instance" mode="pass2">
  <instance>
    <xsl:apply-templates mode="pass2"/>
    <data>2</data>
    <data>3</data>
  </instance>
 </xsl:template>

 <xsl:template match="model" mode="pass2">
  <model>
   <xsl:apply-templates mode="pass2"/>
   <bind>1</bind>
   <bind>2</bind>
   <bind>3</bind>
  </model>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<xform>
    <xforms>
        <model>
            <instance>
                <data>
                </data>
            </instance>
        </model>
        <bind />
        <bind />
        <bind />
    </xforms>
</xform>

它使用身份规则将其转换为自身,并且第一次传递的结果被捕获在变量中$vPass1。然后第二遍处理当前的结果,在元素下$vPass1添加两个新data的子元素,在instance元素下添加三个bindmodel元素——所以最终的结果是:

<xform>
   <xforms>
      <model>
         <instance>
            <data/>
            <data>2</data>
            <data>3</data>
         </instance>
         <bind>1</bind>
         <bind>2</bind>
         <bind>3</bind>
      </model>
      <bind/>
      <bind/>
      <bind/>
   </xforms>
</xform>
于 2012-05-22T12:27:31.910 回答