check元素在xslt中有值

时间:2012-07-26 10:19:01

标签: xml xslt xpath

如何获取xslt中元素的值。假设我的xml像这样,

<comp>
 <link ref=1>1997</link>
 <link ref=2><?LINK 2008?></link>
</comp>

我需要像这样的输出,

<comp>
  <link ssref=1/><num>1997</num>
  <link ssref=2/><num>2008</num>
</comp>

如果链接有价值我需要获得该值,如果它有这样的<?LINK 2008?>我只需要一年。我使用了以下xsl,但它不起作用。

<xsl:template match ="link">
<xsl:element name ="{local-name(.)}">
  <xsl:attribute name ="sshref">
    <xsl:value-of select ="@ref"/>
  </xsl:attribute>
    </xsl:element>
<xsl:if test="text()">
  <xsl:element name ="num">
    <xsl:value-of select ="link"/>
  </xsl:element>
</xsl:if>
</template>

我知道这个xsl错误我刚发布了一些参考资料。 提前谢谢。

3 个答案:

答案 0 :(得分:3)

首先,你的XML格式不正确,因为属性应该用撇号或引号括起来,但我猜这可能是一个简单的错字。

至于具体问题是处理指令,因此检查text()的 xsl:if 不会选择它。

由于您当前的上下文已经在链接元素上,因此您遇到<xsl:value-of select="link" />的问题,因此这正在寻找另一个链接元素是当前子元素。你可能只想要做这样的事情

<xsl:value-of select="." />

所以,你可以像这样重写你的模板

<xsl:template match="link">
    <xsl:element name="{local-name(.)}">
        <xsl:attribute name="sshref">
            <xsl:value-of select="@ref"/>
        </xsl:attribute>
        <xsl:if test="text()|processing-instruction()">
            <xsl:element name="num">
                <xsl:apply-templates select="text()|processing-instruction()"/>
            </xsl:element>
        </xsl:if>
    </xsl:element>
</xsl:template>

<xsl:template match="processing-instruction()">
    <xsl:value-of select="."/>
</xsl:template>

但是,值得注意的是,通常最好避免使用 xsl:if 元素,而是使用模板匹配的强大功能。请尝试使用此备用XSLT。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="link[text()|processing-instruction()]">
      <link>
         <num>
            <xsl:apply-templates select="text()|processing-instruction()"/>
         </num>
      </link>
   </xsl:template>

   <xsl:template match="link/@ref">
      <xsl:attribute name="ssref">
         <xsl:value-of select="."/>
      </xsl:attribute>
   </xsl:template>

   <xsl:template match="processing-instruction()">
      <xsl:value-of select="."/>
   </xsl:template>

   <xsl:template match="@*|node()[not(self::processing-instruction())]">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

应用于以下XMK

<comp>
   <link ref="1">1997</link>
   <link ref="2"><?LINK 2008?></link>
</comp>

以下是输出:

<comp>
   <link sshref="1">
      <num>1997</num>
   </link>
   <link sshref="2">
      <num>2008</num>
   </link>
</comp>

请注意,除非您需要动态命名的元素,否则无需使用 xsl:element

答案 1 :(得分:2)

您可以执行的最简单的XSLT转换如下所示

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="link/text() | link/processing-instruction()">
    <num><xsl:value-of select="normalize-space()" /></num>
  </xsl:template>

  <xsl:template match="link/@ref">
     <xsl:attribute name="ssref"><xsl:value-of select="."/></xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

它转换

<comp>
 <link ref="1">1997</link>
 <link ref="2"><?LINK 2008?></link>
</comp>

进入所需的结果。

<comp>
 <link ssref="1"><num>1997</num></link>
 <link ssref="2"><num>2008</num></link>
</comp>

答案 2 :(得分:1)

您的XML格式不正确,应该是这样的:

<comp>
  <link ref="1">1997</link>
  <link ref="2"><?LINK 2008?></link>
</comp>

然后您可以使用以下XSLT来获得所需的结果:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:element name="comp">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>
  <xsl:template match="comp/link">
    <xsl:element name="{local-name(.)}">
      <xsl:attribute name="sshref"><xsl:value-of select="@ref"/></xsl:attribute>
    </xsl:element>
    <xsl:if test="text()|processing-instruction()">
      <xsl:element name="num">
        <xsl:apply-templates select="text()|processing-instruction()"/>
      </xsl:element>
    </xsl:if>
  </xsl:template>
  <xsl:template match="processing-instruction()">
    <xsl:value-of select="."/>
  </xsl:template>
</xsl:stylesheet>