如何将两个模板应用于同一组节点,特别是XML中的所有节点

如何将两个模板应用于同一组节点,特别是XML中的所有节点,xml,templates,xslt,removing-whitespace,apply-templates,Xml,Templates,Xslt,Removing Whitespace,Apply Templates,我正在尝试从输入XML文件创建输出XML文件。一些节点需要从输入复制到输出,一些节点需要省略,一些节点的文本将以某种方式修改。然而,除此之外,我还需要从每个节点的文本中删除空白。我假设最好的方法是使用模式或其他属性在同一组节点上调用两个模板,但我不知道如何做到这一点。节点太多,无法对每个节点手动应用修剪() 删除空白的代码本身可以工作(来自另一个Stackoverflow的解决方案),但我不知道如何使用另一个模板修改XML,然后应用这两个模板。我希望解决方案如下: <xsl:templat

我正在尝试从输入XML文件创建输出XML文件。一些节点需要从输入复制到输出,一些节点需要省略,一些节点的文本将以某种方式修改。然而,除此之外,我还需要从每个节点的文本中删除空白。我假设最好的方法是使用模式或其他属性在同一组节点上调用两个模板,但我不知道如何做到这一点。节点太多,无法对每个节点手动应用修剪()

删除空白的代码本身可以工作(来自另一个Stackoverflow的解决方案),但我不知道如何使用另一个模板修改XML,然后应用这两个模板。我希望解决方案如下:

<xsl:template match="/">

做转化工作

跳转到match=“node()”模板


删除空白解决方案:

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

<xsl:template match="text()">
    <xsl:value-of select="normalize-space(.)" />
</xsl:template>

以下是一个示例输入:

<ABC Id="64" Author="FirstName">
    <Note Type="Test" ID="01">
        <Note.1>string     </Note.1>
        <Note.2>
            <Point.1>string2        </Point.1>
            <Point.2>hello</Point.2>
        </Note.2>
    </Note>
</ABC>

一串
string2
你好
预期产出:

<ABC Id="64" Author="FirstName">
   <Note Type="Test" ID="01">
      <Note.1>STRING</Note.1> 
      <Note.2>
         <Point.1>string2</Point.1>
      </Note.2>
    </Note>
</ABC>

一串
string2
注.1是从源代码复制的,转换为大写,并删除了空格。 注2/点1删除了空格。 注.2/点.2不是从源复制的

编辑---我的当前代码。它正确地删除了空格。但是,生成的XML包含源中删除了空格的每个节点,而不是仅包含在第一次转换中复制的节点。我将这些节点存储在一个变量中,然后将该变量传递到我的remove whitespace模板中。关于为什么删除空白模板作用于原始集合而不是变量中包含的集合,您有什么想法吗

  <xsl:template match="/">
    <!--Store the results in a variable called transformation_result-->
    <xsl:variable name="transformation_result">
      <!--Go to the normal transformation template -->
      <xsl:call-template name="transformation"/>
    <!--Results now in $transformation_result -->
    </xsl:variable>    
    <!-- If you want to see what is in the variable -->
    <!--<xsl:copy-of select="$transformation_result"/>-->
    <!-- Go to the template that copies all input -->
    <xsl:call-template name="copy_for_whitespace">
      <!-- The $tranformation_result is the parameter passed in by the name of: input -->
      <xsl:with-param name="input" select="$transformation_result"/>
    </xsl:call-template>
  </xsl:template>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
  <xsl:template name="transformation">
    <imp1:HIJ>
      <xsl:copy-of select="/imp1:HIJ/imp1:ABC">
        <?oracle-xsl-mapper-position imp1:ABC?>
      </xsl:copy-of>
    </imp1:HIJ>
  </xsl:template>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
  <xsl:template name="copy_for_whitespace" match="node()">          
    <xsl:param name="input"/>
    <xsl:variable name="test">
    <xsl:copy>                                                 
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
        </xsl:variable>
    <xsl:copy-of select="$test"/>
  </xsl:template>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
  <xsl:template match="text()">                                     
    <xsl:value-of select="normalize-space()"/>
  </xsl:template>

这不是一个真正的答案,但它太长了,无法发表评论

如果将两个不同的模板(使用模式)应用于相同的节点,将得到两个结果节点。我认为这不是你想要的,所以你需要做两件事中的一件:

(a) 分两步进行转换:将第一组模板应用于源文档中的原始节点,同时将结果传递给变量;然后将第二组模板应用于变量中的(新)节点,这一次将结果引导到输出

(b) 将两个转换合并为一个:不幸的是,您没有向我们展示第一个转换的模板(这就是为什么这不能成为答案),但是作为一个示例,如果您想将节点的文本转换为大写并修剪空白,您可以简单地执行以下操作:

<xsl:template match="Note.1">
    <xsl:copy>
        <xsl:value-of select="normalize-space(upper-case(.))"/>
    </xsl:copy>
</xsl:template>


如果规范化空白是您第二次转换的全部任务,那么我相信选项(b)将是更好的选择。

将帮助我们了解您试图实现的目标,如果您可以发布示例输入和预期输出。我已经更新了帖子。希望输入、输出和重新措辞的帮助。您的“当前代码”似乎与问题完全无关。谢谢!这对我有点帮助。我需要给你一个建议,而不是b,因为有太多的节点,无法将函数单独应用于每个节点。对此我不太确定。
<xsl:template match="Note.1">
    <xsl:copy>
        <xsl:value-of select="normalize-space(upper-case(.))"/>
    </xsl:copy>
</xsl:template>