Xml 基于父动态属性动态添加属性并设置值

Xml 基于父动态属性动态添加属性并设置值,xml,xslt,xpath,dynamically-generated,Xml,Xslt,Xpath,Dynamically Generated,大家好,我正在尝试转换此xml: <element> <element> <element> </element> </element> <element> </element> </element> <xsl:template match="@*|node()" mode="copying"> <xsl:copy

大家好,我正在尝试转换此xml:

<element>
    <element>
      <element>

      </element>
    </element>
    <element>

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

  <xsl:template match="*[not(self::newline or self::tab or self::space)]" mode="copying">
    <xsl:copy>
      <xsl:apply-templates select="@*" mode="copying"/>

      <xsl:attribute name="test">
        <xsl:choose>
          <xsl:when test="parent::*">
            <xsl:value-of select="concat(../@test,'    ')"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="''"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:apply-templates select="node()" mode="copying"/>
    </xsl:copy>
  </xsl:template>

为此:

<element test="">
    <element test="f">
      <element test="ff">

      </element>
    </element>
    <element test="f">

    </element>
</element>

因此,concat无论父/@test拥有什么,都要使用“f”等等

我目前有以下xml:

<element>
    <element>
      <element>

      </element>
    </element>
    <element>

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

  <xsl:template match="*[not(self::newline or self::tab or self::space)]" mode="copying">
    <xsl:copy>
      <xsl:apply-templates select="@*" mode="copying"/>

      <xsl:attribute name="test">
        <xsl:choose>
          <xsl:when test="parent::*">
            <xsl:value-of select="concat(../@test,'    ')"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="''"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:apply-templates select="node()" mode="copying"/>
    </xsl:copy>
  </xsl:template>


但它只是忽略父属性的值。有人能帮我吗?

使用XSLT2.0,您可以使用

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

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

    <xsl:template match="*[not(self::newline or self::tab or self::space)]">
        <xsl:param name="test" tunnel="yes" select="''"/>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="test" select="$test"/>
            <xsl:apply-templates select="node()">
                <xsl:with-param name="test" tunnel="yes" select="concat($test, 'f')"/>
            </xsl:apply-templates>
        </xsl:copy>

    </xsl:template>
</xsl:transform>

使用XSLT 1.0时,您需要确保标识转换模板(第一个模板)以及可能传递参数的所有其他模板:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:template match="@*|node()">
        <xsl:param name="test"/>
        <xsl:copy>
            <xsl:apply-templates select="@*|node()">
                <xsl:with-param name="test" select="concat($test, 'f')"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*[not(self::newline or self::tab or self::space)]">
        <xsl:param name="test" select="''"/>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="test">
                <xsl:value-of select="$test"/>
            </xsl:attribute>
            <xsl:apply-templates select="node()">
                <xsl:with-param name="test" select="concat($test, 'f')"/>
            </xsl:apply-templates>
        </xsl:copy>

    </xsl:template>
</xsl:transform>


您的输入元素没有任何
test
属性,您的整个样式表(与所有样式表一样)在输入树上工作,而不是在动态创建的结果节点上工作。因此,您需要将任何值作为参数传递,并连接该参数值并将其作为属性插入。我该怎么做你说的?你能给我举个例子吗?你能使用XSLT2.0处理器吗?使用隧道属性更容易。不,我被迫使用XSLT1.0,因为某些原因,我认为使用匹配的模板不能使用参数。我不需要“隧道”属性,没有它就可以工作。谢谢!