0

XSLTを使用して1つのXML(XHTML)ファイルから別のファイルに変換する必要があります。変換のルールは次のとおりです。

  1. <div id="ta12" class="bl" style="dis:bl">に置き換える必要があります<div class="pass" value="50">
  2. id ="t0b"と"t1b"の値は、それぞれid="ta0b8"と"ta3b8"に置き換える必要があります。
  3. <input type="radio" name="o0" id="t0"/>に置き換える必要があり<input type="radio" name="key0b8" value="0" id="ta0q" class="block" /> ます(そして同様にファイル内で)

入力ファイル:

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-type" content="text/html;  charset=utf-8" />
    </head>  
    <body>
      <div class="iDev">
      <div id="ta12" class="bl" style="dis:bl"></div>

        <div class="q">
          <div id="t0b" class="block">1<span style="color">TEXT1</span>
          </div><br />
          T <input type="radio" name="o0" id="t0"/> 
          F <input type="radio" name="op0" id="f0"/>
          <div id="sfb"></div>
        </div><br />

        <div class="q">
          <div id="t1b" class="block">2<span style="color">TEXT2</span>
          </div><br />
          T <input type="radio" name="o1" id="t1" /> 
          F <input type="radio" name="op1" id="f1" />
          <div id="sfb"></div>
        </div>
      </div>
    </body>
    </html>

出力ファイル:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;  charset=utf-8" />
</head>
<body>
  <div class="iDev">
  <div class="pass" value="50"></div>

    <div class="q">
      <div id="ta0b8" class="block">1<span style="color">TEXT1</span>
      </div><br />
      T<input type="radio" name="key0b8" value="0" id="ta0q" />
      F<input type="radio" name="key0b8" value="1" id="ta1q" />
      <div id="sfb"></div>
    </div><br />

    <div class="q">
      <div id="ta3b8" class="block">2 <span style="color">TEXT2</span>
      </div><br />
      T<input type="radio" name="key3b8" value="0" id="ta0q3" />
      F<input type="radio" name="key3b8" value="1" id="ta1q3" />
      <div id="sfb"></div>
    </div>
  </div>
</body>
</html>

XSLTで、入力ファイル全体を含むIDテンプレートを作成し、必要な変更を加えようとしています。私は最初の仕事をすることができます-

<xsl:template match="xhtml:div[@id='ta12']">
  <xsl:attribute name="class">pa</xsl:attribute>
  <xsl:attribute name="value">10</xsl:attribute>
</xsl:template>

出力では、必要なDivタグが生成されますが、<div class="iDev">タグは削除されます。誰かが与えられた入力から望ましい出力を生成するための解決策を教えてもらえますか?ありがとう!

4

1 に答える 1

2

これがあなたの質問の焦点であるように思われるので、私はあなたの最初のルールに取り組むつもりです。ルール2と3についてサポートが必要な場合は、それらについて個別に質問してください。

一般に、XSLT 1.0が要素を(深くはない)コピーするためのソリューションのパターンは、次のようになります。非深くとは、子ノードを削除することを意味します。

リスト1

<xsl:template match="some-element-pattern">
  <xsl:copy>
   <xsl:copy-of select="@*" />
   <xsl:attribute name="my-attrib-to-set">value-to-set</xsl:attribute>
  </xsl:copy>
</xsl:template>

または、直接コピー以外の属性処理の可能性がある場合は、xsl:copy-ofをxsl:apply-templatesに置き換えることができます。xsl:apply-templatesはより一般的な形式です。

したがって、このソリューションパターンをケースに適用すると、必要なテンプレートは...

リスト2

<xsl:template match="xhtml:div[@id='ta12']">
  <xsl:copy>
   <xsl:copy-of select="@*" />
   <xsl:attribute name="class">pa</xsl:attribute>
   <xsl:attribute name="value">10</xsl:attribute>
  </xsl:copy>
</xsl:template>

NB。以前のソリューションでは、この非効率的なテンプレートを提供した可能性があります...

リスト3

<xsl:template match="xhtml:div[@id='ta12']">
  <xsl:copy>
   <xsl:apply-templates select="@*[not(@class)]" />
   <xsl:attribute name="class">pa</xsl:attribute>
  </xsl:copy>
</xsl:template>

私は今、これが間違っていることに気づきました。述語not(@class)は無意味であり、常にtrueを返します。これは、属性:: axisがフォーカス項目が属性である場合、常に空のシーケンスを返すためです。リスト3の背後にある考え方は、一致した入力div要素にクラス属性がある場合のクラス属性の無関係な処理を排除することでした。リスト2よりもこの種の効率を本当に実現したい場合は、XSLT 1.0でリスト4として実行できますが、コードはやや醜いので、それだけの価値があるかどうかはわかりません。

リスト4

<xsl:template match="xhtml:div[@id='ta12']">
  <xsl:copy>
   <xsl:apply-templates select="@*[local-name()!='class']
                                  [local-name()!='value']" />
   <xsl:attribute name="class">pa</xsl:attribute>
   <xsl:attribute name="value">10</xsl:attribute>
  </xsl:copy>
</xsl:template>

リスト4は、null名前空間にあるクラスと値に対してのみ機能します。問題の属性が名前空間にある場合は、いくつかの変更が必要です。

そして、これがあなたのための最後のオプションです。xsl:copyの一般性を犠牲にする準備ができていて、属性値テンプレートのジューシーな骨髄を吸いたい場合は、リスト5を使用できます。リスト5では、「pa」と「va」を属性値テンプレートに置き換えることができます。 、 要求に応じ。このソリューションのさらなる欠点は、@ class属性と@value属性が子xsl:apply-templates内で処理されないようにする必要があることです。そうしないと、意図したリテラルが上書きされます。値。

リスト5

<xsl:template match="xhtml:div[@id='ta12']">
  <xhtml:div class="pa" value="va">
   <xsl:apply-templates select="@*[local-name()!='class']
                                  [local-name()!='value']" />
  </xhtml:div>
</xsl:template>

最後に、XSLT 1.0にのみ関心があることは承知していますが、少しおもしろいことに、XSLT2.0のソリューションの一般的なパターンについて説明します。これをリスト6に示します。

リスト6

<xsl:template match="some-element-pattern">
  <xsl:copy>
   <xsl:apply-templates select="@* except @my-attrib-to-set" />
   <xsl:attribute name="my-attrib-to-set">value-to-set</xsl:attribute>
  </xsl:copy>
</xsl:template>
于 2012-07-31T05:49:56.953 に答える