【问题标题】:Get a single value from multiple attribute values of XML using xslt使用 xslt 从 XML 的多个属性值中获取单个值
【发布时间】:2012-02-17 11:19:51
【问题描述】:

我有一个 xml,我想要使用 XSL 文件在“标题”中定义的属性。我想检索“abc”和“cdf”值的样式值

<catalog>
    <cd>
       <title style="abc:true;cdf:false"  att2="false">Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
</catalog>

我试过了

 <td><xsl:value-of select="substring-before(substring-after(@style,'abc:'),';')"/></td>

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    这是一种通用转换,允许处理包含不定数量的名称-值对的字符串

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="/">
      <xsl:variable name="vStyle" select="/*/*/title/@style"/>
    
      The value for 'abc' is : <xsl:text/>
      <xsl:call-template name="getValueOfName">
       <xsl:with-param name="pText" select="$vStyle"/>
       <xsl:with-param name="pName" select="'abc'"/>
      </xsl:call-template>
    
      The value for 'cdf' is : <xsl:text/>
      <xsl:call-template name="getValueOfName">
       <xsl:with-param name="pText" select="$vStyle"/>
       <xsl:with-param name="pName" select="'cdf'"/>
      </xsl:call-template>
    
    
      The value for 'xyz' is : <xsl:text/>
      <xsl:call-template name="getValueOfName">
       <xsl:with-param name="pText" select="$vStyle"/>
       <xsl:with-param name="pName" select="'xyz'"/>
      </xsl:call-template>
     </xsl:template>
    
     <xsl:template name="getValueOfName">
      <xsl:param name="pText"/>
      <xsl:param name="pName"/>
    
      <xsl:choose>
          <xsl:when test="not(string-length($pText) > 0)"
            >***Not Found***</xsl:when>
          <xsl:otherwise>
            <xsl:variable name="vPair" select=
             "substring-before(concat($pText, ';'), ';')"/>
    
             <xsl:choose>
               <xsl:when test=
               "$pName = substring-before(concat($vPair, ':'), ':')">
    
                 <xsl:value-of select="substring-after($vPair, ':')"/>
               </xsl:when>
               <xsl:otherwise>
                 <xsl:call-template name="getValueOfName">
                   <xsl:with-param name="pText" select=
                      "substring-after($pText, ';')"/>
                   <xsl:with-param name="pName" select="$pName"/>
                 </xsl:call-template>
               </xsl:otherwise>
             </xsl:choose>
          </xsl:otherwise>
      </xsl:choose>
     </xsl:template>
    </xsl:stylesheet>
    

    应用于提供的 XML 文档时

    <catalog>
        <cd>
            <title style="abc:true;cdf:false"  att2="false">Empire Burlesque</title>
            <artist>Bob Dylan</artist>
            <country>USA</country>
            <company>Columbia</company>
            <price>10.90</price>
            <year>1985</year>
        </cd>
    </catalog>
    

    产生想要的结果

      The value for 'abc' is : true
    
      The value for 'cdf' is : false
    
    
      The value for 'xyz' is : ***Not Found***
    

    解释

    getValueOfName 模板是一个通用模板,它找到包含指定 pName 的名称-值对,然后输出该值 -- 或者如果根本找不到该名称,则输出字符串 ***Not Found*** .

    模板首先从字符串中获取第一个名称-值对并对其进行处理。如果pName 不存在于当前名称-值对中,则模板会在当前名称-值对之后的文本上递归调用自身。

    【讨论】:

    • 现在我可以得到 cdf 的值,正如你之前向我解释的那样
    • 如果文本变成这样 帝国滑稽剧
    • 我得到了我的问题的答案,你可以通过
    • @Librak:对于您上次评论中提出的问题,有一个更优雅的解决方案。请把它作为一个新问题提出,我很乐意回答。
    【解决方案2】:

    我怀疑您的问题与您引用 @style 属性的方式有关。

    如果您使用的是 XPath 2.0,则可以在 / 运算符右侧使用函数调用(例如 substring-after、substring-before)。所以这会起作用:

    /catalog/cd/title/substring-before(substring-after(@style,'abc:'),';')
    

    在 XPath 1.0 中,你不能这样做,每个 / 右边的东西必须是一个轴步骤(不是函数调用),所以你必须使用:

    substring-before(substring-after(/catalog/cd/title/@style,'abc:'),';') 
    

    【讨论】:

    • catalog/cd/title/substring-after(substring-before(@style,';'),'abc:')" 我正在使用这个 Xpath 表达式来获取值是否可以..正确如果我错了,我
    • 是的,/catalog/cd/title/substring-after(substring-before(@style,';'),'abc:') 应该可以工作。
    • 此处需要 NodeTest。 catalog/cd/title/-->substring-before
    • 我不知道 m 使用什么 XSL 处理器,但这条线早上工作正常.... :(
    • 我认为这是由于 @style 属性被引用的方式(以及正在使用的 XPath 版本)。请尝试更新答案中的 XPath 1.0 版本。
    【解决方案3】:

    我认为你很接近:

      <!-- abc -->
      <xsl:value-of 
           select="substring-after(
                   substring-before(/catalog/cd/title/@style,';'),'abc:')"/>
      <!-- cdf -->
     <xsl:value-of 
          select="substring-after(
                  substring-after(/catalog/cd/title/@style,';'),'cdf:')"/>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-18
      • 2013-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多