7

多肢選択式のクイズを任意のXML形式からHTMLに変換するとします。各選択肢は<li>、結果ドキュメントでHTMLタグとして表されます。それぞれの選択肢について、その選択肢が正解だった場合のHTMLclassを追加したいと思います。さらに、その選択肢がユーザーによって選択されたものである場合は、のクラスをに追加します。したがって、選択が送信されたものと同様に正しいものである場合、はのを持っている必要があります。correct<li>submitted<li><li>classcorrect submitted

私の知る限り、空白で区切られた属性値はXMLデータモデルの一部ではないため、XSLTを介して直接作成することはできません。ただし、これを行うには、クラスの可能なすべての組み合わせに対して1つの条件付きコードを散らかすよりも良い方法があると感じています(この例では受け入れられますが、より複雑なシナリオでは扱いにくいです)。

どうすればこれをエレガントな方法で解決できますか?

望ましい結果の例:

<p>Who trained Obi-Wan Kenobi?</p>
<ul>
    <li>Mace Windu</li>
    <li class="correct submitted">Qui-Gon Jinn</li>
    <li>Ki-Adi-Mundi</li>
    <li>Yaddle</li>
</ul>
4

3 に答える 3

11

まず、XMLの属性値の空白には何の問題もありません。大まかに言えば、属性値の正規化は、ドキュメントの解析時に空白文字をスペースに変換し、隣接するスペースを1つのスペースに折りたたむことができますが、空白は確実に許可されます。編集:これについての詳細は以下を参照してください。

Matthew Wilsonのアプローチでは、コメントで述べているように、可能な値の間に空白を含めることができません。しかし、彼のアプローチは基本的に健全です。ジグソーパズルの最後の部分は、冗長スペースが嫌いなことです。これらは、normalize-spaceXPath関数を使用して排除できます。

次のスタイルシートは、すべての要素をまとめたものです。入力ドキュメントには何の影響も与えないため、テスト目的で、任意のXMLドキュメントに対して、またはそれ自体に対しても実行して、出力が要件を満たしていることを確認できます。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:variable name="foo0" select="false()"/>
  <xsl:variable name="bar0" select="true()"/>

  <xsl:variable name="foo1" select="true()"/>
  <xsl:variable name="bar1" select="false()"/>

  <xsl:variable name="foo2" select="true()"/>
  <xsl:variable name="bar2" select="true()"/>

  <xsl:template match="/">

    <xsl:variable name="foobar0">
      <xsl:if test="$foo0"> foo</xsl:if>
      <xsl:if test="$bar0"> bar</xsl:if>
    </xsl:variable>

    <xsl:variable name="foobar1">
      <xsl:if test="$foo1"> foo</xsl:if>
      <xsl:if test="$bar1"> bar</xsl:if>
    </xsl:variable>

    <xsl:variable name="foobar2">
      <xsl:if test="$foo2"> foo</xsl:if>
      <xsl:if test="$bar2"> bar</xsl:if>
    </xsl:variable>

    <li>
      <xsl:attribute name="class">
        <xsl:value-of select="normalize-space($foobar0)"/>
      </xsl:attribute>
    </li>
    <li>
      <xsl:attribute name="class">
        <xsl:value-of select="normalize-space($foobar1)"/>
      </xsl:attribute>
    </li>
    <li>
      <xsl:attribute name="class">
        <xsl:value-of select="normalize-space($foobar2)"/>
      </xsl:attribute>
    </li>

  </xsl:template>
</xsl:stylesheet>

編集:属性の値内の個別のコンポーネントを区切るスペースの問題に加えて:XML仕様では、IDREFSやNMTOKENSなど、いくつかの有効な構成要素を属性タイプとして定義しています。最初のケースはNamesプロダクションと一致し、2番目のケースはNMTokensプロダクションと一致します。これらのプロダクションは両方とも、スペースで区切られた適切なタイプの複数の値を含むものとして定義されています。したがって、単一の属性の値としてのスペースで区切られた値のリストは、XML情報セットの固有のコンポーネントです。

于 2009-10-26T17:58:00.877 に答える
6

私の頭の上から、次のようなスペースで区切られたリストを作成できます。

<li>
    <xsl:attribute name="class">
        <xsl:if cond="...">correct</xsl:if>
        <xsl:if cond="...">submitted</xsl:if>
  </xsl:attribute>
</li>
于 2009-10-26T15:48:49.077 に答える
2

私の知る限り、空白で区切られた属性値は XML データ モデルの一部ではないため、XSLT を介して直接作成することはできません。

XML 言語 (HTML はそうではなく、XHTML はそうです) に変換する場合を除き、XSLT 出力の XML の有効性について心配する必要はありません。これは何でもかまいませんし、XML に準拠する必要はありません!

于 2009-10-26T15:51:40.413 に答える