3

私はこの XSLT の世界の初心者です。単一の XML ノードに存在する値を分割するという問題に直面しています。

たとえば、入力 XML には次のデータが含まれています。

<Employee>
  <FirstName>AAA</FirstName>
  <LastName>BBB</LastName>
  <MobileNo>9999999999-6666666666-7777777777</MobileNo>
</Employee>

上記の例では、従業員は複数の携帯電話番号を持つことができるため、すべての携帯電話番号が 1 つの XML ノードにマージされます<MobileNo>9999999999ハイフン (-) を使用して携帯電話番号を区切ります。は最初の携帯電話番号、6666666666は 2 番目の携帯電話番号、は 3 番目の携帯電話番号を意味し7777777777ます。従業員は、任意の数の携帯電話番号を持つことができます。

Myy 出力 XML は、次の構造を持つ必要があります。

<Employee>
  <FirstName>AAA</FirstName>
  <LastName>BBB</LastName>
  <MobileNo>9999999999</MobileNo>
  <MobileNo>6666666666</MobileNo>
  <MobileNo>7777777777</MobileNo>
</Employee>

では、XSLT 1.0 を使用してこれを実現するにはどうすればよいでしょうか。

あなたの助けに感謝します。

4

2 に答える 2

4

これは、ダッシュで区切られた任意の数の文字列を「分割」する、完全で短く単純な(no xsl:choose、no xsl:when、no xsl:otherwise)XSLT1.0変換です。

<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="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="MobileNo" name="split">
  <xsl:param name="pText" select="."/>

  <xsl:if test="$pText">
   <MobileNo>
     <xsl:value-of select="substring-before(concat($pText, '-'), '-')"/>
   </MobileNo>

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

この変換が提供されたXMLドキュメントに適用される場合:

<Employee>
    <FirstName>AAA</FirstName>
    <LastName>BBB</LastName>
    <MobileNo>9999999999-6666666666-7777777777</MobileNo>
</Employee>

必要な正しい結果が生成されます。

<Employee>
   <FirstName>AAA</FirstName>
   <LastName>BBB</LastName>
   <MobileNo>9999999999</MobileNo>
   <MobileNo>6666666666</MobileNo>
   <MobileNo>7777777777</MobileNo>
</Employee>

説明

  1. 名前付きテンプレート()を再帰的に呼び出しsplitます。

  2. 停止条件は、渡されたパラメーターが空のノードセット/文字列であることです。

  3. 不要な条件付き命令を回避するためのセンチネルの使用。

于 2012-06-02T15:25:24.967 に答える
0

これを再帰的な名前付きテンプレートとして記述する必要があります。以下のコードはその考えを示しています。

ここでの名前付きテンプレートsplit-mobileには、文字列を分割する必要がある可能性のあるハイフンを含む文字列が渡されます。

substring-before最初の番号をフェッチするための呼び出し。文字列にハイフンが含まれていない場合、これは空の文字列(falseと評価されます)を返します。

要素は、要素内の<xsl:choose>最初の数値を出力し、ハイフンでつながれた場合は文字列の残りの部分を<MobileNo>呼び出します。substring-beforeそれ以外の場合は、文字列全体が出力されます。

<xsl:template match="MobileNo">
  <xsl:call-template name="split-mobile" >
    <xsl:with-param name="numbers" select="text()" />
  </xsl:call-template>
</xsl:template>


<xsl:template name="split-mobile">

  <xsl:param name="numbers" />
  <xsl:variable name="number" select="substring-before($numbers, '-')" />

  <xsl:choose>

    <xsl:when test="$number">
      <MobileNo>
        <xsl:value-of select="$number" />
      </MobileNo>
      <xsl:call-template name="split-mobile">
        <xsl:with-param name="numbers" select="substring-after($numbers, '-')"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <MobileNo>
        <xsl:value-of select="$numbers" />
      </MobileNo>
    </xsl:otherwise>

  </xsl:choose>

</xsl:template>
于 2012-06-02T13:00:02.150 に答える