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

时间:2015-01-30 07:03:49

标签: html xslt

hy,我有这个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>

元素标识符将其值更改为属性的值,然后删除属性

但问题是我可以弄清楚如何对所有元素进行循环,我将第一个元素值(虚拟)更改为其属性值(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>

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

<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>

请帮助一个菜鸟 cheerz

2 个答案:

答案 0 :(得分:2)

  

我也尝试创建一个循环来遍历所有标识符元素,   创建一个新元素并将其节点值设置为属性值,   但我无法弄清楚正确的语法

简单地说:

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>

不需要“循环”:第二个模板与identifier匹配,并将依次应用于所有匹配的元素。

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

答案 1 :(得分:0)

试试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>

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