1

XMLをLaTeX(次にHTML)に変換するためにXSLTテンプレートを作成しています。XSLTはそのために作られたものではないと思いますが、機能します。私の唯一の問題はテキストのフォーマットです。テキストの一部の行で太字または斜体の単語を使用したい場合、構文はたとえばHTMLでは「<i> </ i>」ですが、LaTeXでは「\textit{}」です。

1つの解決策は、「i」をテンプレートとして宣言することですが、遭遇したテキストブロックごとに「自動的に」適用できるかどうかわかりません(すべてのテンプレートで明示的に呼び出したくない)。

申し訳ありませんが、私はこのテクノロジーの初心者です。おそらく非常に単純な解決策が存在しますが、今回はGoogleが私を助けてくれませんでした。

任意の提案をいただければ幸いです。

編集:例:

Xsl:

<xsl:template match="one">
<xsl:apply-templates select="two"/>
</xsl:template>

XML:

<one>
<two>Some text with <i>italic</i> words</two>
</one>

必要な出力:

"Some text with \textit{italic} words"

そして、私はしたくない:

<xsl:apply-templates select="i"/>

すべてのテンプレートで

だから私は「グローバルに」「i」テンプレートを適用する方法を探しています。

4

2 に答える 2

3

これと同じくらい簡単です:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>
    
 <xsl:template match="i">
     <xsl:text>\textit{</xsl:text>
     <xsl:apply-templates/>
     <xsl:text>}</xsl:text>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<one>
    <two>Some text with <i>italic</i> words</two>
</one>

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

Some text with \textit{italic} words

説明:

XSLT 処理モデルは、XSLT プログラマーが特定のノードに一致するテンプレートを提供しない場合に備えて、XML ドキュメントの既定の処理が提供される多数の組み込みテンプレートを使用します。

特に、任意の要素ノードの組み込み<xsl:apply-templates/>テンプレートは、そのすべての子にテンプレートが適用されるように発行します。

テキスト ノードの組み込みテンプレートは、このテキスト ノードを出力にコピーすることです。

これは、ノードが対応する組み込みテンプレートとまったく同じことを行う必要がある場合、ノードにテンプレートを提供する必要がないことを意味します。

これにより、要素のみが残ります。つまりi、テンプレート マッチングを提供しiます。子を処理した結果を "\textit{" と "}" で囲むだけです。

注意してください:

<xsl:apply-templates><xsl:call-template><xsl:for-each><xsl:choose>、および<xsl:when>を1 つ指定しなくても、複雑な変換を表現することは完全に可能です。<xsl:otherwise><xsl:if>

これは、これらの命令の 1 つまたはいずれかが広く使用される「プルスタイル」とは対照的に、「プッシュ スタイル」と呼ばれます。

「プッシュ」スタイルは、問題の最も宣言的なソリューションを表現しますが、「プル スタイル」変換は、より「命令的な」ソリューションを表現します。

これは XSLT の精神に則っており、常にできるだけ多くの「プッシュ」コードを生成することをお勧めします

于 2012-10-30T15:24:51.627 に答える
0

編集:OPのXMLとXSLに基づいて、最後に完全なXSLを追加しました

これは単なる仮定です。なぜなら、コメントでDimitreが指摘しているように、XSL、入力、または目的の出力を正確に確認できないからです。ただし、このようなものが必要な場合があります。

<xsl:template match="//i">
   <xsl:text>\textit{</xsl:text>
   <xsl:apply-templates select="@*|node()"/>
   <xsl:text>}</xsl:text>
</xsl:template>


  <!-- or with namespace -->

<xsl:template match="//*[namespace-uri()='http://www.w3.org/1999/xhtml' and local-name()='i']">
   <xsl:text>\textit{</xsl:text>
   <xsl:apply-templates select="@*|node()"/>
   <xsl:text>}</xsl:text>
</xsl:template>



<!-- assumes there is a copy happening like: -->
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

そのようなテンプレートをXSLに追加すると、それぞれに対して実行されるはずです。入力で見つかりました。

出力(HTMLドキュメントをコピーするだけのXSLに入れると)は次のようになります。

<!-- before -->
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>test</title>
  </head>
  <body>
    <p>
      <i>This is Only a Test</i>
    </p>
  </body>
</html>


<!-- after -->
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>test</title>
  </head>
  <body>
    <p>
      \textit{This is Only a Test}
    </p>
  </body>
</html>

もっと教えていただければ、もっと具体的に更新します。

編集:OPのコード(最終的に提供された)に基づく完全な例

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

  <xsl:template match="one">
    <xsl:apply-templates select="two"/>
  </xsl:template>

  <xsl:template match="//i">
    <xsl:text>\textit{</xsl:text>
    <xsl:apply-templates select="@*|node()"/>
    <xsl:text>}</xsl:text>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
于 2012-10-30T15:07:23.247 に答える