2

Ruby などに関連する質問を見ました。このケースをカバーする回答はありませんでした。

XSLT を使用して XML ドキュメントを変換しています。XSLT と XPATH を使用するアプリケーションがまだ 1.0 であるため、私は XSLT 1.0 を使用せざるを得ません。

正規表現を使用して XSL に埋め込まれた Javascript 関数を使用しますか?

次のようなxmlコードがあります。

<document>
<content name="PROD_MAJ_CLS_CD" type="text" vse-streams="2" u="20" action="cluster" weight="1">2</content>
<content name="PART_DESC_SHORT" type="text" vse-streams="2" u="22" action="cluster" weight="1">SCREW-ROCKER</content>
</document>

name="PART_DESC_SHORT" に括弧と括弧を含めることができる content 属性

ありがとう、ポール

4

1 に答える 1

0

あなたの例では、括弧はどれも一致せず、すべてが開き括弧です。その場合、一致しない括弧と括弧を削除するタスクは、すべての括弧と括弧を削除することになります。translateこれは、次の関数を使用して最も簡単に実行できます。

<xsl:value-of select="translate(.,'([','')"/>

実際に一致する中括弧を保持し、フォームの入力を に変換する必要がある場合a(b[c]d(eab[c]deXSLT でこれを行う最も簡単な方法は、入力文字列と、これまでに処理された素材を記録するスタックの 2 つのパラメーターを取る再帰的な名前付きテンプレートを使用することです。(スタックは、選択したセパレーターで区切られた文字列のシーケンスであり、入力に表示されないようにすることができます。入力が属性値からのものとして表示&amp;#x9;されるため、おそらく安全な選択になります(データ プロデューサーが数字参照を使用しない限り、入力から正規化されています)。ただし、必要|||never-use-this-string-in-a-part-description|||に応じて代わりに使用できます)。

最初の呼び出しでは、入力文字列だけを渡し、スタックをデフォルトで空にします。

空でない入力を使用する呼び出しごとに、テンプレートは入力ストリームから 1 文字を取り出し、それを使用して正しいことを行います。

  • "(" と "[" の場合、新しい文字列をスタックにプッシュします。
  • スタックの一番上のアイテムの最初の文字に一致する "]" と ")" の場合、スタックを 2 回ポップし、アイテム 2、アイテム 1 (古い一番上のアイテム)、および文字 "]" または ")" を連結し、連結をスタックにプッシュします。
  • 一致しない「]」と「)」については、入力のバランスが悪いので、何かをする必要があります。(ここのコードは文字を削除します。)
  • その他の文字については、スタックの一番上の項目に追加します。

したがって、スタック上のすべての項目は、一番下の項目を除き、まだ一致していない開き括弧または括弧で始まります。一致するたびに、括弧で囲まれた文字列がスタックの次の項目に追加されるため、スタック サイズが小さくなります。

入力文字列が使い果たされ、スタックに複数の項目がある場合、スタックの一番上の項目の先頭の中括弧を取り除き、一番上の項目 (中括弧を除く) を次の項目に追加する必要があります。

スタックが 1 つのアイテムになると、そのアイテムには必要な文字列が含まれます。

ここに XSLT があります。

<xsl:template name="paren-match-or-strip">
  <xsl:param name="input"/>
  <xsl:param name="stack"/>

  <xsl:variable name="char" 
                select="substring($input,1,1)"/>
  <xsl:variable name="stacktop" 
                select="substring-before($stack,$sep)"/>
  <xsl:variable name="stackrest" 
                select="substring-after($stack,$sep)"/>

  <xsl:choose>
    <xsl:when test="not($input = '')">
      <xsl:choose>
        <xsl:when test="$char = '(' or $char = '['">
          <!--* Push another potential-left-brace on the stack *-->
          <xsl:call-template name="paren-match-or-strip">
            <xsl:with-param name="input" 
                            select="substring($input,2)"/>
            <xsl:with-param name="stack" 
                        select="concat(
                                $char,
                                $sep,
                                $stack
                                )"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:when test="($char = ']' and substring($stacktop,1,1) = '[')
                        or 
                        ($char = ')' and substring($stacktop,1,1) = '(')
                        ">
          <!--* Match the left brace at the top of the stack *-->
          <xsl:variable name="stacktop2" 
                        select="substring-before($stackrest,$sep)"/>
          <xsl:variable name="stackrest2" 
                        select="substring-after($stackrest,$sep)"/>

          <xsl:call-template name="paren-match-or-strip">
            <xsl:with-param name="input" 
                            select="substring($input,2)"/>
            <xsl:with-param name="stack" 
                        select="concat(
                                $stacktop2,
                                $stacktop,
                                $char,
                                $sep,
                                $stackrest
                                )"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:when test="$char = ']' or $char = ')'">
          <!--* Unmatched right brace, drop it silently *-->      
          <xsl:call-template name="paren-match-or-strip">
            <xsl:with-param name="input" 
                            select="substring($input,2)"/>
            <xsl:with-param name="stack" 
                        select="$stack"/>
          </xsl:call-template>
        </xsl:when>     
        <xsl:otherwise>
          <xsl:call-template name="paren-match-or-strip">
            <xsl:with-param name="input" 
                            select="substring($input,2)"/>
            <xsl:with-param name="stack" 
                            select="concat(
                                    $stacktop,
                                    $char,
                                    $sep,
                                    $stackrest
                                    )"/>
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:when test="$input = '' and contains($stackrest,$sep)">
      <!--* Input is exhausted and at least one unmatched
          * parenthesis is on the stack.
          *-->
      <xsl:variable name="stacktop2" 
                    select="substring-before($stackrest,$sep)"/>
      <xsl:variable name="stackrest2" 
                    select="substring-after($stackrest,$sep)"/>

      <xsl:call-template name="paren-match-or-strip">
        <xsl:with-param name="input" 
                        select="$input"/>
        <xsl:with-param name="stack" 
                        select="concat(
                                $stacktop2,
                                substring($stacktop,2),
                                $sep,
                                $stackrest2
                                )"/>
      </xsl:call-template>

    </xsl:when>
    <xsl:otherwise>
      <!--* input is exhausted, stack only has one item *-->
      <xsl:value-of select="substring-before($stack,$sep)"/>
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>
于 2012-08-19T21:44:30.033 に答える