<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
<!-- 
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 2001, Sun
 * Microsystems., http://www.sun.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 -->
  <s1 title="lang() function">
  <ul>
    <li><link anchor="functionality">Functionality</link></li>
    <li><link anchor="implementation">Implementation</link></li>    
  </ul>
  <anchor name="functionality"/>
  <s2 title="Functionality">

  <p>The <code>xml:lang</code> can be used to determine the language for a node or
  a node-set. The attribute can be used to store language-specific data in an
  XML document:</p>

  <source>
    &lt;phrases&gt;
      &lt;greeting xml:lang="en"&gt;Hello!&lt;/greeting&gt;
      &lt;greeting xml:lang="no"&gt;Hei!&lt;/greeting&gt;
      &lt;greeting xml:lang="fr"&gt;Salut!&lt;/greeting&gt;
      &lt;greeting xml:lang="es"&gt;Hola!&lt;/greeting&gt;
      &lt;greeting xml:lang="de"&gt;Sweinhund!&lt;/greeting&gt;
    &lt;/phrases&gt;
  </source>

  <p>The XSL stylesheet can use the <code>lang()</code> function to select the
  element with the desired language:</p>

  <source>
    &lt;xsl:template match="greeting"&gt;
      &lt;xsl:if test="lang("de")&gt;
        &lt;xsl:value-of select="."/&gt;
        &lt;xsl:text&gt; Grossglucklicher wunche!&lt;/xsl:text&gt;
      &lt;/xsl:if&gt;
    &lt;/xsl:template&gt;
  </source>
</s2> <anchor name="implementation"/>
<s2 title="Implementation">

  <p>The DOM interface has been given a method that returns the language for
  a given node. The language is returned as a string (on whatever format is
  used in the XML document - should be iso), and may be null if no language is
  defined.</p>

  <source>
    public String DOM.getLanguage(int node);
  </source>

  <p>The BasisLibrary class has a static method that will compare the language
  of the context node with some other language and return the result as a
  boolean.</p>

  <source>
    public static boolean BasisLibrary.testLanguage(String language, DOM dom, int node);
  </source>

  <p>The compiled code for the <code>lang()</code> method calls this method in the
  BasisLibrary and leaves the result on the stack for the calling element.</p>
  </s2>
</s1>
