Как получить подстроку подстроки из узла xml, используя xslt - PullRequest
0 голосов
/ 12 мая 2018

Как получить подстроку подстроки из узла xml, используя xslt?

например,

input:

<node>This Is W3 School</node>

output:

<node>TIWS</node>

Здесь я хочу получить первую букву каждой подстроки через пробел.

Ответы [ 5 ]

0 голосов
/ 18 мая 2018

Если вы застряли с XSLT 1.0, вы можете использовать рекурсивный вызов шаблона для обработки строки.

Пример ...

Ввод XML

<doc>
    <node>This Is W3 School</node>
    <node>One Two Three Four Five Six</node>
    <node>Hello </node>
    <node>      X   Y   Z      </node>
    <node/>    
</doc>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="node">
    <xsl:copy>
      <xsl:call-template name="first_letters"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="first_letters">
    <xsl:param name="input" select="normalize-space()"/>
    <xsl:variable name="remaining" select="substring-after($input,' ')"/>
    <xsl:value-of select="substring($input,1,1)"/>
    <xsl:if test="$input">
      <xsl:call-template name="first_letters">
        <xsl:with-param name="input" select="$remaining"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

Вывод XML

<doc>
   <node>TIWS</node>
   <node>OTTFFS</node>
   <node>H</node>
   <node>XYZ</node>
   <node/>
</doc>

Fiddle: http://xsltfiddle.liberty -development.net / 6qVRKw1

0 голосов
/ 15 мая 2018

Спасибо за все ваши ответы. Поскольку я использую xslt versio: 1.0, у меня есть функции подстроки для получения желаемого результата.

  <?xml version="1.0" encoding="UTF-8"?>
  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:template match="node">
      <node1>
        <xsl:value-of select="substring(substring-before(normalize-space(substring-after(//node,'')),' '),1,1)"/>
        <xsl:value-of select="substring(substring-after(normalize-space(substring-after(//node,'')),' '),1,1)"/>
        <xsl:value-of select="substring(substring-before(normalize-space(substring-after(normalize-space(substring-after(//node,' ')),' ')),' '),1,1)"/>
        <xsl:value-of select="substring(substring-after(normalize-space(substring-after(normalize-space(substring-after(//node,' ')),' ')),' '),1,1)"/>
    </node1>
    </xsl:template>     
</xsl:stylesheet>

Пожалуйста, дайте мне знать, если я могу уменьшить код в той же версии xslt 1.0

0 голосов
/ 12 мая 2018

Другой вариант - использовать fn:replace() с регулярным выражением и группой захвата:

fn:replace("This Is W3 School", "([A-Z])\w+\s?", "$1")
0 голосов
/ 12 мая 2018
<xsl:template match="node">
       <xsl:variable name="s" select="tokenize(.,' ')"/>

    <xsl:element name="node">
        <xsl:for-each select="$s">
        <xsl:value-of select="substring(.,1,1)"/>
        </xsl:for-each>
    </xsl:element>
   </xsl:template>
First of all tokenize the string then use substring for your desire output
0 голосов
/ 12 мая 2018

Вы можете легко использовать tokenize(., ' ') в контексте элемента node для получения последовательности строк, затем вы можете использовать функцию substring для первой буквы, например. в XSLT 3 tokenize(., ' ')!substring(., 1, 1) или в XSLT 2 for $token in tokenize(., ' ') return substring($token, 1, 1).

Затем выведите результат с xsl:value-of например. в XSLT 3

  <xsl:template match="node">
    <xsl:copy>
        <xsl:value-of select="tokenize(., ' ')!substring(., 1, 1)" separator=""/>
    </xsl:copy>
  </xsl:template>

https://xsltfiddle.liberty -development.net / 6qVRKvY

или в XSLT 2 с

  <xsl:template match="node">
    <xsl:copy>
        <xsl:value-of select="for $token in tokenize(., ' ') return substring($token, 1, 1)" separator=""/>
    </xsl:copy>
  </xsl:template>
...