在XSL中使用XPath来选择具有以给定字符串开头的属性名称的节点的所有属性值

问题描述

| 我有一些看起来像这样的xml:
<row>
    <anode myattr1=\"value1\" anotherAttr=\"notthis\">
        blah
    </anode>
    <anothernode myattr1=\"value1\" myattr2=\"value2\" anotherAttr=\"notthis\">
        blahBlah
    </anothernode>
</row>
我想变成这样的东西:
<tr>
    <td title=\"value1\">
        blah
    </td>
    <td title=\"value1\\nvalue2\">
        blahBlah
    </td>
</tr>
因此,我试图使用\“ fn:starts-with \”选择这些属性值,但效果不佳。这是我到目前为止的内容
<xsl:for-each select=\"row\">
    <tr>                        
        <xsl:for-each select=\"./*\">
            <xsl:variable name=\"title\">
                <xsl:for-each select=\"./@[fn:starts-with(name(),\'myattr\')]\">
                    <xsl:value-of select=\".\"/>
                </xsl:for-each>
            </xsl:variable>
            <td title=\"$title\"><xsl:value-of select=\".\"/></td>
        </xsl:for-each>
    </tr>
</xsl:for-each>
但是运行此程序时出现异常。任何帮助,将不胜感激。     

解决方法

简短而简单的转换:
<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=\"/\">
  <tr>
   <xsl:apply-templates/>
  </tr>
 </xsl:template>

 <xsl:template match=\"row/*\">
     <td>
      <xsl:apply-templates select=\"@*[starts-with(name(),\'myattr\')][1]\"/>
      <xsl:value-of select=\".\"/>
     </td>
 </xsl:template>
 <xsl:template match=\"@*[starts-with(name(),\'myattr\')][1]\">
  <xsl:attribute name=\"title\">
   <xsl:value-of select=\".\"/>
   <xsl:apply-templates select=
    \"../@*[starts-with(name(),\'myattr\')][position()>1]\"/>
  </xsl:attribute>
 </xsl:template>

 <xsl:template match=\"@*[starts-with(name(),\'myattr\')][position()>1]\">
  <xsl:value-of select=\"concat(\'\\n\',.)\"/>
 </xsl:template>
</xsl:stylesheet>
当应用于提供的XML文档时:
<row>
    <anode anotherAttr=\"notthis\" myattr1=\"value1\" >
             blah
  </anode>
    <anothernode anotherAttr=\"notthis\" myattr1=\"value1\" myattr2=\"value2\" >
             blahBlah
 </anothernode>
</row>
所需的正确结果产生了:
<tr>
   <td title=\"value1\">
             blah
  </td>
   <td title=\"value1\\nvalue2\">
             blahBlah
 </td>
</tr>