ブログ@kaorun55

HoloLensやKinectなどのDepthセンサーを中心に書いています。

XSL でテキストボックスコンポーネント

ノードセットはこれがやりたいがための前座^^;
これで xsl:call-template を使っていろいろ作れる。
xsl:apply-templates だと match を書かなきゃいかんので、めんどくさいのよね。
#そもそも、そうならないように XML を設計するのか?

こんなん作った

XML

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="textBox.xsl" type="text/xsl" ?>

<root>
  <element>
    <name>
      <label>氏名</label>
      <text>なかむら かおる</text>
    </name>
    <address>
      <label>住所</label>
      <text>ここではないどこか</text>
    </address>
  </element>
</root>

XSL

  • textBox.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exslt="http://exslt.org/common"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="exslt msxsl">

  <!--
  Smart trick - exslt:node-set() in Internet Explorer
  http://www.tkachenko.com/blog/archives/000704.html
  -->

  <msxsl:script language="JScript" implements-prefix="exslt">
    this['node-set'] =  function (x) {
    return x;
    }
  </msxsl:script>

  <xsl:template match="/">
    <HTML>
      <head>
        <title>test</title>
      </head>
      <body>
        <!--氏名を表示-->
        <xsl:call-template name="textBox">
          <xsl:with-param name="node">
            <xsl:copy-of select="root/element/name"/>
          </xsl:with-param>
        </xsl:call-template>
        <br/>
        <!--住所を表示-->
        <xsl:call-template name="textBox">
          <xsl:with-param name="node">
            <xsl:copy-of select="root/element/address"/>
          </xsl:with-param>
        </xsl:call-template>
      </body>
    </HTML>
  </xsl:template>
  
  <!--テキストボックス-->
  <xsl:template name="textBox">
    <xsl:param name ="node"/>

    <!--フォーカス移動のための固有ID-->
    <xsl:variable name="id" select="generate-id(exslt:node-set($node)/child::node()[1])"/>

    <!--ノードセットからラベルとテキストを抽出-->
    <xsl:variable name="label" select="exslt:node-set($node)/node()[1]/label"/>
    <xsl:variable name="text" select="exslt:node-set($node)/node()[1]/text"/>
    
    <!--テキストの前のラベル-->
    <xsl:if test="$label">
      <label>
        <xsl:attribute name="for">
          <xsl:value-of select="$id" />
        </xsl:attribute>
        <xsl:value-of select="$label"/>
      </label>
    </xsl:if>

    <!--テキストボックス-->
    <input>
      <xsl:attribute name="id">
        <xsl:value-of select="$id" />
      </xsl:attribute>
      <xsl:attribute name="value">
        <xsl:value-of select="$text" />
      </xsl:attribute>
    </input>
  </xsl:template>
</xsl:stylesheet>