3

以下の構造の xml ドキュメントがあります。ノード B からテキストを出力したいが、要素 C とテキスト ノード「タイトル」を無視する変換を作成しています。基本的に、「テキストはここに入る」というテキストを抽出し、すべての空白を正規化して新しい要素に出力したいと思います。誰でも助けることができますか?以下は、私がこれまでに試したことです。

Input Doc
<A>
  <B>
    <C>title</C>
     text goes here
  </B>
</A>

Required output doc
<d>text goes here</d>


Solution A:
<xsl:template match="B">
  <d>       
    <xsl:copy-of select="./text()"/>                
  </d>
</xsl:template>

問題: 要素間の空白が保持されるため、次のようになります。

<d>

  Text goes here

</d>

また、ソリューション A のテンプレートで value-of ステートメント ( <xsl:value-of select="./text()"/>) を使用しようとしましたが、これはテキストをまったく返しませんでした。発言に何か問題あるの?

以下を使用して、デフォルトのテキスト処理テンプレートをオーバーライドしたことに言及する必要があります。<xsl:template match="text()" />

ありがとう

4

3 に答える 3

9

<xsl:value-of select="./text()"/>「nothing」が返される理由は、現在のノードのすべての直接の子テキスト ノードで構成される./text()ノードセットが返されるためです。value-ofa ノード セットは、最初の項目の文字列値です。この場合<B>、開始タグと開始タグの間の空白のみのテキスト ノード<C>です。normalize-space(text())ノード セットを文字列 (最初のノード値) に変換し、その文字列内のスペースを正規化するため、同じことが次に最も明白なノードにも当てはまります。代わりに、各子テキスト ノードを個別に正規化する必要があります。

<d>
  <xsl:for-each select="text()">
    <xsl:value-of select="normalize-space(.)"/>
  </xsl:for-each>
</d>

ただし、これについて注意すべきことの 1 つは、次のような入力がある場合です。

<A>
  <B>
    <C>title</C>
     text goes here
    <C>subtitle</C>
     more text here
  </B>
</A>

次に、次の出力が得られます

<d>text goes heremore text here</d>

字幕の両側のビット間にスペースはありません。これが問題である場合は、次のようなトリックを使用できます

<d>
  <xsl:for-each select="text()[normalize-space(.)]">
    <xsl:if test="position() &gt; 1"><xsl:text> </xsl:text></xsl:if>
    <xsl:value-of select="normalize-space(.)"/>
  </xsl:for-each>
</d>

非空白文字を含むテキストノードの子のみを反復処理し、最初の文字以外のすべての前にスペースを追加します。

<d>text goes here more text here</d>
于 2012-12-06T14:30:32.910 に答える
0

このコードを試してください!

使用する代わりに、<copy-of>テンプレートオーバーライドを使用しました!

  1. BをDに置き換えます。

  2. 出力からドロップ<C>します。これで問題の半分が解決されるため、<C>ノードのテキストは出力に表示されません。

  3. 正規化スペース関数をすべてのテキストノードに適用します..余分な空白が消去されます:)

コードは次のとおりです。

  <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" indent="yes"/>
      <xsl:template match="B">
        <d>
          <xsl:apply-templates select="node()"/>
        </d>
      </xsl:template>

      <xsl:template match="C"/>

      <xsl:template match="text()">
        <xsl:value-of select="normalize-space(.)"/>
      </xsl:template>
    </xsl:stylesheet>
于 2012-12-06T14:21:55.217 に答える
0

私が得る最も近いものはchildの選択です://B/child::text()

軸は、現在のchildコンテキストノードの直接の子であるテキストノードのみを返すため、ノードとは一致しませんtitle

于 2012-12-06T14:12:12.953 に答える