Как разобрать строку с разделителями, используя индекс разделителя в xslt? - PullRequest
0 голосов
/ 24 декабря 2010

У меня есть строка с разделителями, которая выглядит следующим образом:

FirstName&LastName&Address1&Address2&City&State&country&

Мне нужно разделить строку на основе индекса появления разделителя.четыре значения в строке, я должен получить выходные данные в двух разных переменных, где первая переменная должна иметь строку с первыми четырьмя значениями, а вторая переменная имеет оставшуюся строку.

Я не хочу использовать exslt или любые другие расширения.Пожалуйста, помогите мне с простым решением.

    Input:

    <xsl:variable name="index" select='4' />

<xsl:variable name="delimitedString" select='FirstName&amp;LastName&amp;Address1&amp;Address2&amp;City&amp;State&amp;country&amp;' />

Output:

<xsl:variable name="requiredString">
FirstName&amp;LastName&amp;Address1&amp;Address2&amp;
</xsl:variable>

<xsl:variable name="remainingString">
City&amp;State&amp;country&amp;
</xsl:variable>

1 Ответ

2 голосов
/ 24 декабря 2010

Это преобразование :

<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:param name="pSplitIndex" select="4"/>

 <xsl:template match="text()" name="splitAt">
  <xsl:param name="pLeft" select="''"/>
  <xsl:param name="pRight" select="."/>
  <xsl:param name="pSplitAt" select="$pSplitIndex"/>
  <xsl:param name="pDelim" select="'&amp;'"/>

  <xsl:choose>
    <xsl:when test=
     "not(string-length($pRight))
     or
      not(contains($pRight, $pDelim))
     ">
     <t1>
       <xsl:value-of select="concat($pLeft, $pRight)"/>
     </t1>
     <t2/>
    </xsl:when>
    <xsl:otherwise>
     <xsl:choose>
      <xsl:when test="$pSplitAt = 0">
       <t1><xsl:value-of select="$pLeft"/></t1>
       <t2><xsl:value-of select="$pRight"/></t2>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="splitAt">
         <xsl:with-param name="pLeft" select=
          "concat($pLeft, substring-before($pRight, $pDelim), $pDelim)
          "/>
         <xsl:with-param name="pRight"
          select="substring-after($pRight, $pDelim)"/>
         <xsl:with-param name="pSplitAt" select="$pSplitAt -1"/>
         <xsl:with-param name="pDelim" select="$pDelim"/>
        </xsl:call-template>
      </xsl:otherwise>
     </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

при применении к этому документу XML :

<t>FirstName&amp;LastName&amp;Address1&amp;Address2&amp;City&amp;State&amp;country&amp;</t>

дает два необходимыхстроки, получающиеся в результате разбиения /t/text() на четвертом &amp; разделителе :

<t1>FirstName&amp;LastName&amp;Address1&amp;Address2&amp;</t1>
<t2>City&amp;State&amp;country&amp;</t2>

Вы можете определить переменную, скажем vrtfSplitResult, тело которой является результатом применения шаблонов к текстовому узлусодержащий строку.Затем, если вы можете использовать расширение xxx:node-set(), две переменные, которые вы хотите определить:

<xsl:variable name="requiredString" 
     select="xxx:node-set($vrtfSplitResult)/*/t1">

<xsl:variable name="remainingString" 
     select="xxx:node-set($vrtfSplitResult)/*/t2">

В случае, если вам не разрешено использовать даже функцию расширения xxx:node-set() , тогда вы должны использовать похожий, названный шаблон: getStartingString.Это имеет в значительной степени логику шаблона splitAt, приведенного выше:

<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:param name="pSplitIndex" select="4"/>

 <xsl:template match="text()">
   <xsl:variable name="vrequiredString">
    <xsl:call-template name="getStartingString"/>
   </xsl:variable>
   <xsl:variable name="vremainingString" select=
    "substring-after(.,$vrequiredString)"/>

   <t>
     <t1><xsl:value-of select="$vrequiredString"/></t1>
     <t2><xsl:value-of select="$vremainingString"/></t2>
   </t>
 </xsl:template>

 <xsl:template name="getStartingString">
  <xsl:param name="pLeft" select="''"/>
  <xsl:param name="pRight" select="."/>
  <xsl:param name="pSplitAt" select="$pSplitIndex"/>
  <xsl:param name="pDelim" select="'&amp;'"/>

  <xsl:choose>
    <xsl:when test=
     "not(string-length($pRight))
     or
      not(contains($pRight, $pDelim))
     ">
       <xsl:value-of select="$pLeft"/>
    </xsl:when>
    <xsl:otherwise>
     <xsl:choose>
      <xsl:when test="$pSplitAt = 0">
       <xsl:value-of select="$pLeft"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="getStartingString">
         <xsl:with-param name="pLeft" select=
          "concat($pLeft, substring-before($pRight, $pDelim), $pDelim)
          "/>
         <xsl:with-param name="pRight"
          select="substring-after($pRight, $pDelim)"/>
         <xsl:with-param name="pSplitAt" select="$pSplitAt -1"/>
         <xsl:with-param name="pDelim" select="$pDelim"/>
        </xsl:call-template>
      </xsl:otherwise>
     </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к тому же XML-документу, требуемый, правильный результат выдается снова :

<t>
    <t1>FirstName&amp;LastName&amp;Address1&amp;Address2&amp;</t1>
    <t2>City&amp;State&amp;country&amp;</t2>
</t>
...