XSL 转换 - 如何将属性值设置为元素值

XSL transformation - how to set attribute value to element value

嘿,我有这个 HTML

<mods>
<name type="personal" ID="">
<role>
<roleTerm authority="marcrelator" type="text">Author</roleTerm>
</role>
<identifier type="type1" value="value1">dummy</identifier>
<identifier type="type2" value="value1">dummy</identifier>
<namePart type="given"/>
<namePart type="family"/>
</name>

我想将其转换为

<mods>
<name type="personal" ID="">
<role>
<roleTerm authority="marcrelator" type="text">Author</roleTerm>
</role>
<identifier type="type1">value1</identifier>
<identifier type="type2">value2</identifier>
<namePart type="given"/>
<namePart type="family"/>
</name>

元素 identifier 将其值更改为属性 value 的值,然后属性 value被删除。

但问题是我可以弄清楚如何对所有元素进行循环,我将第一个元素值(虚拟)更改为它的属性值(value1),第二个获得第一个元素值 (value1) 也是,而不是它的值 (value2)

这样做的代码是:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!--empty template suppresses this attribute-->

    <!--identity template copies everything forward by default-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/mods/name/identifier/text()">
    <xsl:value-of><xsl:value-of select="/mods/name/identifier/@value" /></xsl:value-of>       
    </xsl:template>

   <xsl:template match="@value"/>

</xsl:stylesheet>

我还尝试创建一个循环遍历所有 identifier 元素,创建一个新元素并将其节点值设置为属性值,但我无法找出正确的方法语法

<xsl:template match="/mods/name/identifier">
<xsl:for-each select="node()">
        <xsl:element name="identifier"><xsl:value-of select="/@value" /></xsl:element>       
</xsl:for-each>
</xsl:template>

请帮助菜鸟 欢呼

i also tried creating a loop to go thru all the identifier elements, create a new element and set its node value to the attribute value, but i cant figure out the right syntax

简单的怎么样:

XSLT 1.0

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

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

<xsl:template match="identifier">
    <xsl:copy>
        <xsl:copy-of select="@type"/>
        <xsl:value-of select="@value"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

不需要 "loop":第二个模板匹配 identifier 并将依次应用于所有匹配的元素。

另请注意,一旦处于匹配元素的上下文中,您就希望使用指向子节点的相对 路径。否则,您将始终选择 第一个 引用节点(按文档顺序,从根开始)。

试试这个 xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!--empty template suppresses this attribute-->

  <!--identity template copies everything forward by default-->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/mods/name/identifier">
    <xsl:element name="{local-name()}">
      <xsl:for-each select="@*">
        <xsl:choose>
          <xsl:when test="name()='type'">
            <xsl:attribute name="{name()}">
              <xsl:value-of select="."/>
            </xsl:attribute>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="."/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

我没有在单独的模板中分离属性逻辑