XSLT3 joining values with separator

大憨熊 提交于 2020-06-17 13:23:07

问题


I'm pretty new to XSLT and I've been struggling to replicate the solution mentioned here XSL for-each: how to detect last node? for longer than I'm willing to admit :(

I've setup this fiddle. https://xsltfiddle.liberty-development.net/naZXVFi

I was hoping I could use just the value-of + separator, vs choose / when xslt tools, as it did seem more idiomatic.

  • I can't get the separator to show up;
  • nor can I select just the child of skill, I always get the descendants too. That's to say, I shouldn't see any detail in the output.
  • bonus: not sure why that meta tag is not self closing (warning in the html section)

Desired output: skill1, skill2, skill3, skill4, skill5 (no comma space for the last one)

Any help would be greatly appreciated. Thanks.

EDIT: including the code here too: xml: (need to add ref to xslt):

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?> <!-- not in fiddle -->

<skills>
    <skill>skill1</skill>
    <skill>skill2</skill>
    <skill>skill3
        <details>
            <detail>detail1</detail>
            <detail>detail2</detail>
        </details>
    </skill>
    <skill>skill4</skill>
    <skill>skill5</skill>
</skills>

And test.xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="html" indent="yes" html-version="5"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>.NET XSLT Fiddle Example</title>
      </head>
      <body>
         <xsl:for-each select="/skills/skill">
            <xsl:value-of select="." separator=", "/>
        </xsl:for-each>
      </body>
    </html>


  </xsl:template>

</xsl:stylesheet>

回答1:


In general, with XSLT 2/3 to output a sequence separated by some separator string, you simply use xsl:value-of select="$sequence" with the appropriate separator string in the separator attribute (and no for-each):

  <xsl:template match="skills">
    <xsl:value-of select="skill/text()[normalize-space()]/normalize-space()" separator=", "/>
  </xsl:template>

https://xsltfiddle.liberty-development.net/naZXVFi/1

In most cases you would just need select="skill" separator=", " but given your descendants and the white space you seem to want to eliminate the select expression above is a bit more complicated.




回答2:


Martin has given you the detailed work-through to get the final result including getting rid of the extra spaces etc, but at a high level, here's how to use xsl:value-of with separator correctly.

You have:

  <body>
     <xsl:for-each select="/skills/skill">
        <xsl:value-of select="." separator=", "/>
    </xsl:for-each>
  </body>

This says that for each skill node, take the content of that node and display it. Notably, the value-of only sees one skill at a time, so there is nothing to join with the comma separator.

The answer which would get you what you want is:

  <body>
        <xsl:value-of select="/skills/skill" separator=", "/>
  </body>

This says to take the set of skill nodes and display them joined by comma separators. You can see the output at https://xsltfiddle.liberty-development.net/naZXVFi/4



来源:https://stackoverflow.com/questions/62005912/xslt3-joining-values-with-separator

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!