【问题标题】:check element has value in xslt检查元素在 xslt 中有值
【发布时间】:2012-07-26 10:19:00
【问题描述】:

如何获取 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>

如果链接有价值,我需要得到那个价值,如果它有这样的&lt;?LINK 2008?&gt;,我只需要一年。我使用了以下 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 错误,我只是发布一些参考。 提前致谢。

【问题讨论】:

    标签: xml xslt xpath


    【解决方案1】:

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

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

    你在&lt;xsl:value-of select="link" /&gt; 处也遇到了问题,因为你当前的上下文已经在 link 元素上,所以它正在寻找另一个 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,尽管您的 XSLT 可以进一步简化。看我的回答。
    【解决方案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>
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-05
        相关资源
        最近更新 更多