3

誰かが私に手を貸してくれることを願っています。この問題は私を数日間困惑させてきました。私の問題の根本は、2つの要素の間のドキュメント順にすべてのノードにマークアップを追加したいということです。

次のようなXMLを持つドキュメントがあります。

<Employees>
  <Employee>
    <Title>Mr.</Title>
    <FirstName>John</FirstName>
    <LastName>Doe</LastName>
</Employee>
  <Employee>
    <Title>Mr.</Title>
    <FirstName>Tom</FirstName>
    <LastName>Doe</LastName>
  </Employee>
</Employees>

検索ヒットをマークアップするOracleの「マークアップ」関数を使用して、文字列「John Doe」を検索すると、次のようなXML結果が得られます。

<Employees>
  <Employee>
    <Title>Mr.</Title>
    <FirstName><hitStart/>John</FirstName>
    <LastName>Doe<hitEnd/></LastName>
  </Employee>
  <Employee>
    <Title>Mr.</Title>
    <FirstName>Tom</FirstName>
    <LastName>Doe</LastName>
  </Employee>
</Employees>

これをヒットを強調するXHTMLに変換したいと思います。たとえば、次のXHTMLは有用な結果になります。

<TABLE>
  <TR>
    <TD>Mr. <b style="color:red">John Doe</b></TD>
  <TR>
  <TR>
    <TD>Tom Doe</TD>
  </TR>
</TABLE>

apply-templatesまたは名前付きテンプレートを使用してドキュメント内を移動するスタイルシートを作成しようとしましたが、機能させることができません。ノードがhitStart要素とhitEnd要素内にあるかどうかを示すパラメーターを渡すことができないため、apply-templatesの使用には注意が必要です。名前付きテンプレートの使用は、テキストノードと要素ノードを異なる方法で処理する必要があるため注意が必要です。これはXSLT1.0では実行できません。助けていただければ幸いです。

ありがとう、ブライアン

助けてくれたみんなに感謝します!!!! あなたたちは素晴らしいです!

これが私が決めたものです:

<xsl:template match="/*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select="node()[1]"/>
    </xsl:copy>
    <xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="text()[preceding::*[self::hitStart or self::hitEnd][1][self::hitStart]
and following::*[self::hitStart or self::hitEnd][1][self::hitEnd]]">
    <span style="color:red;font-style:italic;font-weight:bold"><xsl:value-of select="."/></span>
    <xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="hitStart|hitEnd">
    <xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
4

3 に答える 3

3

この変換

<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()[1]"/>
    </xsl:copy>
    <xsl:apply-templates select="following-sibling::node()[1]"/>
  </xsl:template>

 <xsl:template match=
   "text()
      [preceding::*[self::hitStart or self::hitEnd][1][self::hitStart]
     and
       following::*[self::hitStart or self::hitEnd][1][self::hitEnd]
      ]">
    <xsl:value-of select="concat('*** ', ., ' ***')"/>
  </xsl:template>

 <xsl:template match="hitStart|hitEnd">
    <xsl:apply-templates select="following-sibling::node()[1]"/>
  </xsl:template>
 </xsl:stylesheet>

提供されたXMLドキュメントに対して適用された場合:

<Employees>
  <Employee>
    <Title>Mr.</Title>
    <FirstName><hitStart/>John</FirstName>
    <LastName>Doe<hitEnd/></LastName>
  </Employee>
  <Employee>
    <Title>Mr.</Title>
    <FirstName>Tom</FirstName>
    <LastName>Doe</LastName>
  </Employee>
</Employees>

hitStartと要素の間のすべてのテキストノードを強調表示しますhitEnd。3つのアスタリスクで囲み、必要な正しい結果を生成します

<Employees>
   <Employee>
      <Title>Mr.</Title>
      <FirstName>*** John ***</FirstName>
      <LastName>*** Doe ***</LastName>
   </Employee>
   <Employee>
      <Title>Mr.</Title>
      <FirstName>Tom</FirstName>
      <LastName>Doe</LastName>
   </Employee>
</Employees>

説明

「きめ細かい」IDルールの使用とオーバーライド。

于 2012-12-10T15:28:32.780 に答える
1

それは理想的ではありませんが、あなたは次のような迅速で汚いことをすることができます...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" encoding="utf-8" indent="no"/>

    <xsl:template match="/">
        <table>
            <xsl:apply-templates />
        </table>
    </xsl:template>

    <xsl:template match="FirstName[hitStart]">
        <span class="alert"><xsl:value-of select="."/>&#160;</span>
    </xsl:template>
    <xsl:template match="FirstName">
        <xsl:value-of select="."/>&#160;
    </xsl:template>
    <xsl:template match="LastName[hitEnd]">
        <span class="alert"><xsl:value-of select="."/></span>
    </xsl:template>
    <xsl:template match="LastName">
        <xsl:value-of select="."/>
    </xsl:template>
    <xsl:template match="Employees/Employee">
        <tr>
            <td>
                <xsl:apply-templates select="Title"/>
            </td>
            <td>
                <xsl:apply-templates select="FirstName | LastName"/>
            </td>
        </tr>
    </xsl:template>
</xsl:stylesheet>
于 2012-12-10T17:57:38.660 に答える
0

終了なしで要素を開始し、開始要素なしで要素を終了するエラーを防ぐために、出力エスケープの無効化を使用する単純なソリューション。

<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xhtml" indent="yes"/>

    <xsl:template match="/Employees">
        <TABLE>
            <xsl:apply-templates select="Employee"/>
        </TABLE>
    </xsl:template>

    <xsl:template match="Employee">
        <TR>
            <TD><xsl:apply-templates/></TD>
        </TR>
    </xsl:template>

    <xsl:template match="hitStart">
        <xsl:value-of disable-output-escaping="yes" select="'&lt;b style=&quot;color:red&quot;&gt;'"/>
    </xsl:template>

    <xsl:template match="hitEnd">
        <xsl:value-of disable-output-escaping="yes" select="'&lt;/b&gt;'"/>
    </xsl:template>
</xsl:transform>
于 2012-12-10T22:10:46.970 に答える