Как я могу достичь функции SPLIT в XSLT 1.0 - PullRequest
2 голосов
/ 12 марта 2011

У меня есть следующий сценарий. У меня есть узел TEAM-MEMBERS, который имеет имя в формате фамилия, имя

<TEAM-MEMBER><LONG-NAME>Last Name, First Name</LONG-NAME></TEAM-MEMBER>

Я хочу преобразовать это в

<CONTACT><FIRSTNAME>First Name</FIRSTNAME><LASTNAME>Last Name</LASTNAME></CONTACT>

В основном я хочу разделить значение узла <LONG-NAME> на ,

Как мне добиться этого с помощью XSLT 1.0

Этот XSLT будет использоваться BizTalk Server, поэтому я ищу только некоторые решения XSLT 1.0

Спасибо

Karthik

Ответы [ 3 ]

2 голосов
/ 12 марта 2011

Вот полное решение XSLT 1.0, в котором используется общий шаблон «split» , который разбивает строку на несколько подстрок, предоставляя разделитель для обозначения границы между подстроками:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="TEAM-MEMBER">
  <xsl:variable name="vrtfSplitWords">
   <xsl:call-template name="split">
    <xsl:with-param name="pText" select="."/>
   </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="vSplitWords"
  select="ext:node-set($vrtfSplitWords)/*"/>

  <CONTACT>
   <FIRSTNAME><xsl:value-of select="$vSplitWords[2]"/></FIRSTNAME>
   <LASTNAME><xsl:value-of select="$vSplitWords[1]"/></LASTNAME>
  </CONTACT>
 </xsl:template>

 <xsl:template name="split">
  <xsl:param name="pText" select="."/>
  <xsl:param name="pDelim" select="', '"/>
  <xsl:param name="pElemName" select="'word'"/>

  <xsl:if test="string-length($pText)">
   <xsl:element name="{$pElemName}">
    <xsl:value-of select=
     "substring-before(concat($pText,$pDelim),
                       $pDelim
                      )
     "/>
   </xsl:element>

   <xsl:call-template name="split">
    <xsl:with-param name="pText" select=
    "substring-after($pText,$pDelim)"/>
    <xsl:with-param name="pDelim" select="$pDelim"/>
    <xsl:with-param name="pElemName" select="$pElemName"/>
   </xsl:call-template>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному документу XML:

<TEAM-MEMBER><LONG-NAME>Last Name, First Name</LONG-NAME></TEAM-MEMBER>

желаемый, правильный результат получается :

<CONTACT>
   <FIRSTNAME>First Name</FIRSTNAME>
   <LASTNAME>Last Name</LASTNAME>
</CONTACT>

II. Решение с использованием FXSL

В этом преобразовании используется шаблон str-split-to-words из FXSL:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
 exclude-result-prefixes="ext"
>
  <xsl:import href="strSplit-to-Words.xsl"/>
  <xsl:output indent="yes" omit-xml-declaration="yes"/>

   <xsl:strip-space elements="*"/>
   <xsl:output indent="yes" omit-xml-declaration="yes"/>

   <xsl:param name="pmaxLines" select="10"/>

    <xsl:template match="/">
      <xsl:variable name="vwordNodes">
        <xsl:call-template name="str-split-to-words">
          <xsl:with-param name="pStr" select="/"/>
          <xsl:with-param name="pDelimiters"
                          select="',()'"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:apply-templates select=
       "ext:node-set($vwordNodes)/*[normalize-space()]"/>

    </xsl:template>

    <xsl:template match="word[normalize-space()][1]">
      <FIRSTNAME>
       <xsl:value-of select="normalize-space()"/>
      </FIRSTNAME>
    </xsl:template>

    <xsl:template match="word[normalize-space()][2]">
      <MIDNAME>
       <xsl:value-of select="normalize-space()"/>
      </MIDNAME>
    </xsl:template>

    <xsl:template match="word[normalize-space()][last()]">
      <LASTNAME>
       <xsl:value-of select="normalize-space(.)"/>
      </LASTNAME>
    </xsl:template>
</xsl:stylesheet>

применительно к этому XML-документу (сделан более сложным):

<TEAM-MEMBER><LONG-NAME>First Name, (Jr.), Last Name</LONG-NAME></TEAM-MEMBER>

желаемый, правильный результат выдается :

<FIRSTNAME>First Name</FIRSTNAME>
<MIDNAME>Jr.</MIDNAME>
<LASTNAME>Last Name</LASTNAME>

Do Note :

Шаблон str-split-to-words принимает несколько разделителей. Таким образом, в этом преобразовании используются следующие разделители: ',', '(' и ')'

0 голосов
/ 12 марта 2011

использовал substring-after() и substring-before(), чтобы обойти раскол

0 голосов
/ 12 марта 2011

Вам нужен рекурсивный именованный шаблон. К счастью, это уже написано: ищите str:tokenize на http://www.exslt.org.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...