【问题标题】:XSLT modify attribute value at EXACT element by passing the original value to a templateXSLT 通过将原始值传递给模板来修改 EXACT 元素的属性值
【发布时间】:2021-03-29 04:40:45
【问题描述】:

我正在努力让这个名为 XSLT 的可憎之物工作。我需要在 EXACT 路径中获取一个 EXACT 属性,将其原始值传递给模板,然后用模板的结果重写该值。

我有一个这样的文件:

<?xml version="1.0" encoding="windows-1251"?>
<File>
  <Document ReportYear="17">
        ...
        ...
  </Document>
</File>

所以我做了一个这样的 XSLT:

<?xml version="1.0" encoding="windows-1251"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

    <xsl:output method="xml" encoding="windows-1251" indent="yes" />

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

    <xsl:template name="formatYear">
        <xsl:param name="year" />
        <xsl:value-of select="$year + 2000" />
    </xsl:template>

    <xsl:template match="File/Document">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:attribute name="ReportYear">
                <xsl:call-template name="formatYear">
                    <xsl:with-param name="year" select="@ReportYear" />
                </xsl:call-template>
            </xsl:attribute>
        </xsl:copy>
        <xsl:apply-templates />
    </xsl:template>

</xsl:stylesheet>

这很好用,只是它会立即关闭 &lt;Document&gt; 标记并将其内容紧跟其后。

另外,我可以在不重复两次的情况下处理ReportYear 属性值吗?我试过current(),但没用。

【问题讨论】:

    标签: xslt xslt-1.0


    【解决方案1】:

    如果您需要使用apply-templates 处理Document 元素的内容并希望将应用模板的结果保留为子元素,那么您需要将apply-templates 移动到copy 内:

    <xsl:template match="File/Document">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="ReportYear">
                <xsl:call-template name="formatYear">
                    <xsl:with-param name="year" select="@ReportYear"/>
                </xsl:call-template>
            </xsl:attribute>
            <xsl:apply-templates/>
        </xsl:copy>     
    </xsl:template>
    

    不知道你为什么不简单地使用

    <xsl:template match="File/Document/@ReportYear">
       <xsl:attribute name="{name()}">
          <xsl:value-of select=". + 2000"/>
       </xsl:attribute>
    </xsl:template>
    

    连同身份转换模板。

    【讨论】:

      【解决方案2】:

      如果您在将模板应用于&lt;Document&gt; 的其余内容之前关闭&lt;xsl:copy&gt;,那么当然&lt;Document&gt; 将在&lt;Document&gt; 的其余内容出现在输出中之前关闭。

      <xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:msxsl="urn:schemas-microsoft-com:xslt"
          exclude-result-prefixes="msxsl"
      >
          <xsl:output method="xml" encoding="windows-1251" indent="yes" />
      
          <xsl:template match="@* | node()">
              <xsl:copy>
                  <xsl:apply-templates select="@* | node()" />
              </xsl:copy>
          </xsl:template>
      
          <xsl:template match="Document">
              <xsl:copy>
                  <xsl:apply-templates select="@*" />
                  <xsl:attribute name="ReportYear">
                      <xsl:value-of select="@ReportYear + 2000" />
                  </xsl:attribute>
                  <xsl:apply-templates select="node()" />
              </xsl:copy>
          </xsl:template>
      
      </xsl:stylesheet>
      

      输出

      <?xml version="1.0" encoding="windows-1251"?>
      <File>
        <Document ReportYear="2017">
              ...
              ...
        </Document>
      </File>
      

      我认为没有必要仅将 2000 添加到 @ReportYear 的额外模板。但如果必须,您可以像这样简化整个事情

      <xsl:template name="formatYear">
          <xsl:param name="year" select="@ReportYear" />   <!-- you can define a default value -->
          <xsl:value-of select="$year + 2000" />
      </xsl:template>
      

      <xsl:attribute name="ReportYear">
          <xsl:call-template name="formatYear" />  <!-- ...and can use it implicitly here -->
      </xsl:attribute>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-27
        • 1970-01-01
        • 2015-12-04
        • 1970-01-01
        相关资源
        最近更新 更多