JNLP validation

R

Roedy Green

I took Sun's DTD to validate JNLP 6.0 at
http://java.sun.com/dtd/JNLP-6.0.dtd
and ran in through the DTD->XSD converter at
http://www.hitsw.com/xml_utilites/

I then I tried validating one of my JNLP files. It seems to think you
are not supposed to nest <java inside <resources which Sun's example
says is kosher.

Presumably the problem is the DTD->XSD conversion process was flawed.
The XSD is baffling. It seems to show both <java inside <resources and
<resources inside <java.

I wonder if anyone would be willing to look at the xsd to see if it is
broken and why.

There are three pieces:

1. the JNLP 6.0 validating XSD schema.

2. A sample JNLP 6.0 file.

3. a program to use the scheme to validate the JNLP.

In the meantime, I will look for some other conversion utility.

-------------------------------------------------------------------------------------

<?xml version="1.0" encoding="UTF-8" ?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<!-- Schema for a JNLP 6.0, probably needs tweaking -->
<!-- mechanically generated from DTD. Needs tweaking, reorg and
comments to make it more comprehensible -->

<xs:element name="all-permissions" type="xs:string" />

<xs:element name="applet-desc">
<xs:complexType>
<xs:sequence>
<xs:element ref="param" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="height" type="xs:string" use="required" />
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="main-class" type="xs:string" use="required"
/>
<xs:attribute name="width" type="xs:string" use="required" />
<xs:attribute name="documentbase" type="xs:string"
use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="application-desc">
<xs:complexType>
<xs:sequence>
<xs:element ref="argument" minOccurs="0" maxOccurs="unbounded"
/>
</xs:sequence>
<xs:attribute name="main-class" type="xs:string" use="optional"
/>
</xs:complexType>
</xs:element>

<xs:element name="argument">
<xs:complexType mixed="true" />
</xs:element>

<xs:element name="association">
<xs:complexType>
<xs:sequence>
<xs:element ref="description" minOccurs="0" />
<xs:element ref="icon" minOccurs="0" />
</xs:sequence>
<xs:attribute name="extensions" type="xs:string" use="required"
/>
<xs:attribute name="mime-type" type="xs:string" use="required"
/>
</xs:complexType>
</xs:element>

<xs:element name="component-desc" type="xs:string" />

<xs:element name="description">
<xs:complexType mixed="true">
<xs:attribute name="kind" use="optional">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="one-line" />
<xs:enumeration value="short" />
<xs:enumeration value="tooltip" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>

<xs:element name="desktop" type="xs:string" />

<xs:element name="ext-download">
<xs:complexType>
<xs:attribute name="download" use="optional" default="eager">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="lazy" />
<xs:enumeration value="eager" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="part" type="xs:string" use="optional" />
<xs:attribute name="ext-part" type="xs:string" use="required" />
</xs:complexType>
</xs:element>

<xs:element name="extension">
<xs:complexType>
<xs:sequence>
<xs:element ref="ext-download" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="optional" />
<xs:attribute name="href" type="xs:string" use="required" />
<xs:attribute name="name" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="homepage">
<xs:complexType>
<xs:attribute name="href" type="xs:string" use="required" />
</xs:complexType>
</xs:element>

<xs:element name="icon">
<xs:complexType>
<xs:attribute name="height" type="xs:string" use="optional" />
<xs:attribute name="version" type="xs:string" use="optional" />
<xs:attribute name="href" type="xs:string" use="required" />
<xs:attribute name="size" type="xs:string" use="optional" />
<xs:attribute name="kind" type="xs:string" use="optional" />
<xs:attribute name="width" type="xs:string" use="optional" />
<xs:attribute name="depth" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="information">
<xs:complexType>
<xs:sequence>
<xs:element ref="title" />
<xs:element ref="vendor" />
<xs:element ref="homepage" minOccurs="0" />
<xs:element ref="description" minOccurs="0"
maxOccurs="unbounded" />
<xs:element ref="icon" minOccurs="0" maxOccurs="unbounded" />
<xs:element ref="offline-allowed" minOccurs="0" />
<xs:element ref="shortcut" minOccurs="0" />
<xs:element ref="association" minOccurs="0" />
<xs:element ref="related-content" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="locale" type="xs:string" use="optional" />
<xs:attribute name="platform" type="xs:string" use="optional" />
<xs:attribute name="arch" type="xs:string" use="optional" />
<xs:attribute name="os" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="installer-desc">
<xs:complexType>
<xs:attribute name="main-class" type="xs:string" use="optional"
/>
</xs:complexType>
</xs:element>

<xs:element name="j2ee-application-client-permissions"
type="xs:string" />

<xs:element name="j2se">
<xs:complexType>
<xs:sequence>
<xs:element ref="resources" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="required" />
<xs:attribute name="href" type="xs:string" use="optional" />
<xs:attribute name="max-heap-size" type="xs:string"
use="optional" />
<xs:attribute name="java-vm-args" type="xs:string"
use="optional" />
<xs:attribute name="initial-heap-size" type="xs:string"
use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="jar">
<xs:complexType>
<xs:attribute name="main" use="optional" default="false">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="true" />
<xs:enumeration value="false" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="download" use="optional" default="eager">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="eager" />
<xs:enumeration value="lazy" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="version" type="xs:string" use="optional" />
<xs:attribute name="href" type="xs:string" use="required" />
<xs:attribute name="part" type="xs:string" use="optional" />
<xs:attribute name="size" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="java">
<xs:complexType>
<xs:sequence>
<xs:element ref="resources" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="required" />
<xs:attribute name="href" type="xs:string" use="optional" />
<xs:attribute name="max-heap-size" type="xs:string"
use="optional" />
<xs:attribute name="java-vm-args" type="xs:string"
use="optional" />
<xs:attribute name="initial-heap-size" type="xs:string"
use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="jnlp">
<xs:complexType>
<xs:sequence>
<xs:element ref="information" maxOccurs="unbounded" />
<xs:element ref="security" minOccurs="0" />
<xs:element ref="update" minOccurs="0" />
<xs:element ref="resources" minOccurs="0"
maxOccurs="unbounded" />
<xs:choice>
<xs:element ref="application-desc" />
<xs:element ref="applet-desc" />
<xs:element ref="component-desc" />
<xs:element ref="installer-desc" />
</xs:choice>
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="optional" />
<xs:attribute name="href" type="xs:string" use="optional" />
<xs:attribute name="spec" type="xs:string" use="optional" />
<xs:attribute name="codebase" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="menu">
<xs:complexType>
<xs:attribute name="submenu" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="nativelib">
<xs:complexType>
<xs:attribute name="download" use="optional" default="eager">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="eager" />
<xs:enumeration value="lazy" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="version" type="xs:string" use="optional" />
<xs:attribute name="href" type="xs:string" use="required" />
<xs:attribute name="part" type="xs:string" use="optional" />
<xs:attribute name="size" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="offline-allowed" type="xs:string" />

<xs:element name="package">
<xs:complexType>
<xs:attribute name="recursive" use="optional" default="false">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="true" />
<xs:enumeration value="false" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="part" type="xs:string" use="required" />
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>

<xs:element name="param">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="value" type="xs:string" use="required" />
</xs:complexType>
</xs:element>

<xs:element name="property">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="value" type="xs:string" use="required" />
</xs:complexType>
</xs:element>

<xs:element name="related-content">
<xs:complexType>
<xs:sequence>
<xs:element ref="title" minOccurs="0" />
<xs:element ref="description" minOccurs="0" />
<xs:element ref="icon" minOccurs="0" />
</xs:sequence>
<xs:attribute name="href" type="xs:string" use="required" />
</xs:complexType>
</xs:element>

<xs:element name="resources">
<xs:complexType>
<xs:choice>
<xs:element ref="java" />
<xs:element ref="j2se" />
<xs:element ref="jar" />
<xs:element ref="nativelib" />
<xs:element ref="extension" />
<xs:element ref="property" />
<xs:element ref="package" />
</xs:choice>
<xs:attribute name="locale" type="xs:string" use="optional" />
<xs:attribute name="arch" type="xs:string" use="optional" />
<xs:attribute name="os" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>

<xs:element name="security">
<xs:complexType>
<xs:sequence>
<xs:element ref="all-permissions" minOccurs="0" />
<xs:element ref="j2ee-application-client-permissions"
minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>

<xs:element name="shortcut">
<xs:complexType>
<xs:sequence>
<xs:element ref="desktop" minOccurs="0" />
<xs:element ref="menu" minOccurs="0" />
</xs:sequence>
<xs:attribute name="online" use="optional" default="true">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="true" />
<xs:enumeration value="false" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>

<xs:element name="title">
<xs:complexType mixed="true" />
</xs:element>

<xs:element name="update">
<xs:complexType>
<xs:attribute name="check" use="optional" default="timeout">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="always" />
<xs:enumeration value="timeout" />
<xs:enumeration value="background" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="policy" use="optional" default="always">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="always" />
<xs:enumeration value="prompt-update" />
<xs:enumeration value="prompt-run" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>

<xs:element name="vendor">
<xs:complexType mixed="true" />
</xs:element>

</xs:schema>

-------------------------------------------------------------------------------------

<?xml version="1.0" encoding="utf-8"?>

<!-- Do not edit! last regenerated 2008-03-27 07:15 PDT by
ReplicatorSender -->
<jnlp spec="6.0+" codebase="http://mindprod.com/replicator"
href="replicatorreceiverwebsite.jnlp" version="9.8">
<information>
<title>The Replicator 9.8 via website</title>

<vendor>Canadian Mind Products</vendor>
<homepage href="webstart/replicator.html" />

<description>Replicates files via website. Also keeps them up to
date efficiently.</description>
<description kind="short">Replicates files via
website.</description>
<description kind="one-line">Replicates files via
website.</description>
<description kind="tooltip">the Replicator</description>
<!-- relative to codebase, need copy in same dir as jar, and jnlp
file. -->
<icon href="replicatoricon64.png" width="64" height="64"
kind="default" />
<icon href="replicatorsplash.png" width="128" height="128"
kind="splash" />
<!-- online only -->
<!-- create desktop shortcut to run the Replicator -->
<shortcut online="true">
<desktop />
<menu submenu="The Replicator" />
</shortcut>
</information>

<security>
<all-permissions />
</security>

<update check="always" policy="always" />

<resources>
<!-- requires 1.6 -->
<!-- Sun JVM -->
<java version="1.6.0_05"
href="http://java.sun.com/products/autodl/j2se" java-vm-args="-ea"
initial-heap-size="128m" max-heap-size="512m" />
<java version="1.6+"
href="http://java.sun.com/products/autodl/j2se" java-vm-args="-ea"
initial-heap-size="128m" max-heap-size="512m" />
<!-- any vendor -->
<java version="1.6+" java-vm-args="-ea" initial-heap-size="128m"
max-heap-size="512m" />

<!-- application code, download jar before we start. -->
<jar href="replicator.jar" main="true" download="eager" />

<!-- set -D system properties -->
<property name="VIA" value="website" />
<property name="PROJECT_NAME" value="Mindprod.com" />
<property name="UNIQUE_PROJECT_NAME"
value="com.mindprod.replicator" />
<property name="SUGGESTED_RECEIVER_BASE_DIR" value="C:\mindprod"
/>
<property name="SUGGESTED_RECEIVER_ZIP_STAGING_DIR"
value="C:\mpstaging" />
<property name="WEBSITE_ZIP_URL"
value="http://mindprod.com/replicator" />
<property name="SUGGESTED_LAN_ZIP_URL"
value="http://mindprod.com/replicator" />
<property name="KEEP_ZIPS" value="false" />
<property name="UNPACK_ZIPS" value="true" />
<property name="AUTHENTICATION" value="none" />
<property name="DEBUGGING" value="true" />
</resources>

<!-- application class with main method -->
<application-desc main-class="com.mindprod.replicator.Replicator" />

</jnlp>

--------------------------------------------------------------------------------------------------------------


// validating a JNLP document with an XSD schema

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import javax.xml.XMLConstants;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;


/**
* Validate on JNLP file using the Vampqh JNLP XSD schema
* Requires a copy of the Vampqh schema "jnlp1-xml-schema.xsd"
version 1.0
* or "jnlp6-xml-schema.xsd" version 6.0 in the current directory.
*/
public class ValidateJNLP
{
/**
* validate one jnlp file
*
* @param args first name of xsd schema,
* second name of name of the jnlp file to validate,
* e.g. E:\com\mindprod\affirm\affirm.jnlp
*/
public static void main ( String[] args )
{
try
{
// build an XSD-aware SchemaFactory
SchemaFactory schemaFactory = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI );

// hook up mindless org.xml.sax.ErrorHandler implementation.
schemaFactory.setErrorHandler( new JNLPErrorHandler() );

// get the custom xsd schema describing the required format
for my XML files.
Schema schemaXSD = schemaFactory.newSchema( new File (
args[0] ) );

// Create a Validator capable of validating JNLP files
according to to the custom schema.
Validator validator = schemaXSD.newValidator();

// Validate the JNLP file that is supposed to conform to the
custom schema
DocumentBuilder parser =
DocumentBuilderFactory.newInstance().newDocumentBuilder();

// parse the JNLP file on the command line purely as XML and
get a DOM tree represenation.
Document document = parser.parse( new File( args[1] ));

// parse the JNLP tree against the stricter XSD schema
validator.validate( new DOMSource( document ) );
}
catch ( Exception e )
{
e.printStackTrace();
}
} // end main

} // end ValidateJNLP

class JNLPErrorHandler implements ErrorHandler
{
/**
* default contstructor
*/
public JNLPErrorHandler()
{
}

/**
* Receive notification of a warning.
*
* <p>SAX parsers will use this method to report conditions that
* are not errors or fatal errors as defined by the XML
* recommendation. The default behaviour is to take no
* action.</p>
*
* <p>The SAX parser must continue to provide normal parsing events
* after invoking this method: it should still be possible for the
* application to process the document through to the end.</p>
*
* <p>Filters may use this method to report other, non-XML warnings
* as well.</p>
*
* @param exception The warning information encapsulated in a
* SAX parse exception.
* @exception org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
* @see org.xml.sax.SAXParseException
*/
public void warning (SAXParseException exception)
throws SAXException
{
System.err.println( exception );
}


/**
* Receive notification of a recoverable error.
*
* <p>This corresponds to the definition of "error" in section 1.2
* of the W3C XML 1.0 Recommendation. For example, a validating
* parser would use this callback to report the violation of a
* validity constraint. The default behaviour is to take no
* action.</p>
*
* <p>The SAX parser must continue to provide normal parsing
* events after invoking this method: it should still be possible
* for the application to process the document through to the end.
* If the application cannot do so, then the parser should report
* a fatal error even if the XML recommendation does not require
* it to do so.</p>
*
* <p>Filters may use this method to report other, non-XML errors
* as well.</p>
*
* @param exception The error information encapsulated in a
* SAX parse exception.
* @exception org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
* @see org.xml.sax.SAXParseException
*/
public void error (SAXParseException exception)
throws SAXException
{
System.err.println( exception );
}

/**
* Receive notification of a non-recoverable error.
*
* <p><strong>There is an apparent contradiction between the
* documentation for this method and the documentation for {@link
* org.xml.sax.ContentHandler#endDocument}. Until this ambiguity
* is resolved in a future major release, clients should make no
* assumptions about whether endDocument() will or will not be
* invoked when the parser has reported a fatalError() or thrown
* an exception.</strong></p>
*
* <p>This corresponds to the definition of "fatal error" in
* section 1.2 of the W3C XML 1.0 Recommendation. For example, a
* parser would use this callback to report the violation of a
* well-formedness constraint.</p>
*
* <p>The application must assume that the document is unusable
* after the parser has invoked this method, and should continue
* (if at all) only for the sake of collecting additional error
* messages: in fact, SAX parsers are free to stop reporting any
* other events once this method has been invoked.</p>
*
* @param exception The error information encapsulated in a
* SAX parse exception.
* @exception org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
* @see org.xml.sax.SAXParseException
*/
public void fatalError (SAXParseException exception)
throws SAXException
{
System.err.println( exception );
}

} // end JNLPErrorHandler
 
O

Owen Jacobson

I took Sun's DTD to validate JNLP 6.0  athttp://java.sun.com/dtd/JNLP-6.0.dtd
and ran in through the DTD->XSD converter athttp://www.hitsw.com/xml_utilites/

I then I tried validating one of my JNLP files. It seems to think you
are not supposed to nest <java inside <resources which  Sun's example
says is kosher.

Presumably the problem is the DTD->XSD conversion process was flawed.
The XSD is baffling. It seems to show both <java inside <resources and
<resources inside <java.

I wonder if anyone would be willing to look at the xsd to see if it is
broken and why.

There are three pieces:

1. the JNLP 6.0 validating XSD schema.

2. A sample JNLP 6.0 file.

3. a program to use the scheme to validate the JNLP.

In the meantime, I will look for some other conversion utility.

--------------------------------------------------------------------------- ----------

<?xml version="1.0" encoding="UTF-8" ?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<!-- Schema for a JNLP 6.0, probably needs tweaking -->
<!-- mechanically generated from DTD.  Needs tweaking, reorg and
comments to make it more comprehensible -->

  <xs:element name="all-permissions" type="xs:string" />

  <xs:element name="applet-desc">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="param" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute name="height" type="xs:string" use="required" />
      <xs:attribute name="name" type="xs:string" use="required" />
      <xs:attribute name="main-class" type="xs:string" use="required"
/>
      <xs:attribute name="width" type="xs:string" use="required" />
      <xs:attribute name="documentbase" type="xs:string"
use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="application-desc">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="argument" minOccurs="0" maxOccurs="unbounded"
/>
      </xs:sequence>
      <xs:attribute name="main-class" type="xs:string" use="optional"
/>
    </xs:complexType>
  </xs:element>

  <xs:element name="argument">
    <xs:complexType mixed="true" />
  </xs:element>

  <xs:element name="association">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="description" minOccurs="0" />
        <xs:element ref="icon" minOccurs="0" />
      </xs:sequence>
      <xs:attribute name="extensions" type="xs:string" use="required"
/>
      <xs:attribute name="mime-type" type="xs:string" use="required"
/>
    </xs:complexType>
  </xs:element>

  <xs:element name="component-desc" type="xs:string" />

  <xs:element name="description">
    <xs:complexType mixed="true">
      <xs:attribute name="kind" use="optional">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="one-line" />
            <xs:enumeration value="short" />
            <xs:enumeration value="tooltip" />
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

  <xs:element name="desktop" type="xs:string" />

  <xs:element name="ext-download">
    <xs:complexType>
      <xs:attribute name="download" use="optional" default="eager">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="lazy" />
            <xs:enumeration value="eager" />
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="part" type="xs:string" use="optional" />
      <xs:attribute name="ext-part" type="xs:string" use="required" />
    </xs:complexType>
  </xs:element>

  <xs:element name="extension">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ext-download" minOccurs="0"
maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute name="version" type="xs:string" use="optional" />
      <xs:attribute name="href" type="xs:string" use="required" />
      <xs:attribute name="name" type="xs:string" use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="homepage">
    <xs:complexType>
      <xs:attribute name="href" type="xs:string" use="required" />
    </xs:complexType>
  </xs:element>

  <xs:element name="icon">
    <xs:complexType>
      <xs:attribute name="height" type="xs:string" use="optional" />
      <xs:attribute name="version" type="xs:string" use="optional" />
      <xs:attribute name="href" type="xs:string" use="required" />
      <xs:attribute name="size" type="xs:string" use="optional" />
      <xs:attribute name="kind" type="xs:string" use="optional" />
      <xs:attribute name="width" type="xs:string" use="optional" />
      <xs:attribute name="depth" type="xs:string" use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="information">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="title" />
        <xs:element ref="vendor" />
        <xs:element ref="homepage" minOccurs="0" />
        <xs:element ref="description" minOccurs="0"
maxOccurs="unbounded" />
        <xs:element ref="icon" minOccurs="0" maxOccurs="unbounded" />
        <xs:element ref="offline-allowed" minOccurs="0" />
        <xs:element ref="shortcut" minOccurs="0" />
        <xs:element ref="association" minOccurs="0" />
        <xs:element ref="related-content" minOccurs="0"
maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute name="locale" type="xs:string" use="optional" />
      <xs:attribute name="platform" type="xs:string" use="optional" />
      <xs:attribute name="arch" type="xs:string" use="optional" />
      <xs:attribute name="os" type="xs:string" use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="installer-desc">
    <xs:complexType>
      <xs:attribute name="main-class" type="xs:string" use="optional"
/>
    </xs:complexType>
  </xs:element>

  <xs:element name="j2ee-application-client-permissions"
type="xs:string" />

  <xs:element name="j2se">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="resources" minOccurs="0"
maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute name="version" type="xs:string" use="required" />
      <xs:attribute name="href" type="xs:string" use="optional" />
      <xs:attribute name="max-heap-size" type="xs:string"
use="optional" />
      <xs:attribute name="java-vm-args" type="xs:string"
use="optional" />
      <xs:attribute name="initial-heap-size" type="xs:string"
use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="jar">
    <xs:complexType>
      <xs:attribute name="main" use="optional" default="false">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="true" />
            <xs:enumeration value="false" />
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="download" use="optional" default="eager">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="eager" />
            <xs:enumeration value="lazy" />
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="version" type="xs:string" use="optional" />
      <xs:attribute name="href" type="xs:string" use="required" />
      <xs:attribute name="part" type="xs:string" use="optional" />
      <xs:attribute name="size" type="xs:string" use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="java">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="resources" minOccurs="0"
maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute name="version" type="xs:string" use="required" />
      <xs:attribute name="href" type="xs:string" use="optional" />
      <xs:attribute name="max-heap-size" type="xs:string"
use="optional" />
      <xs:attribute name="java-vm-args" type="xs:string"
use="optional" />
      <xs:attribute name="initial-heap-size" type="xs:string"
use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="jnlp">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="information" maxOccurs="unbounded" />
        <xs:element ref="security" minOccurs="0" />
        <xs:element ref="update" minOccurs="0" />
        <xs:element ref="resources" minOccurs="0"
maxOccurs="unbounded" />
        <xs:choice>
          <xs:element ref="application-desc" />
          <xs:element ref="applet-desc" />
          <xs:element ref="component-desc" />
          <xs:element ref="installer-desc" />
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="version" type="xs:string" use="optional" />
      <xs:attribute name="href" type="xs:string" use="optional" />
      <xs:attribute name="spec" type="xs:string" use="optional" />
      <xs:attribute name="codebase" type="xs:string" use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="menu">
    <xs:complexType>
      <xs:attribute name="submenu" type="xs:string" use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="nativelib">
    <xs:complexType>
      <xs:attribute name="download" use="optional" default="eager">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="eager" />
            <xs:enumeration value="lazy" />
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="version" type="xs:string" use="optional" />
      <xs:attribute name="href" type="xs:string" use="required" />
      <xs:attribute name="part" type="xs:string" use="optional" />
      <xs:attribute name="size" type="xs:string" use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="offline-allowed" type="xs:string" />

  <xs:element name="package">
    <xs:complexType>
      <xs:attribute name="recursive" use="optional" default="false">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="true" />
            <xs:enumeration value="false" />
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="part" type="xs:string" use="required" />
      <xs:attribute name="name" type="xs:string" use="required" />
    </xs:complexType>
  </xs:element>

  <xs:element name="param">
    <xs:complexType>
      <xs:attribute name="name" type="xs:string" use="required" />
      <xs:attribute name="value" type="xs:string" use="required" />
    </xs:complexType>
  </xs:element>

  <xs:element name="property">
    <xs:complexType>
      <xs:attribute name="name" type="xs:string" use="required" />
      <xs:attribute name="value" type="xs:string" use="required" />
    </xs:complexType>
  </xs:element>

  <xs:element name="related-content">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="title" minOccurs="0" />
        <xs:element ref="description" minOccurs="0" />
        <xs:element ref="icon" minOccurs="0" />
      </xs:sequence>
      <xs:attribute name="href" type="xs:string" use="required" />
    </xs:complexType>
  </xs:element>

  <xs:element name="resources">
    <xs:complexType>
      <xs:choice>
        <xs:element ref="java" />
        <xs:element ref="j2se" />
        <xs:element ref="jar" />
        <xs:element ref="nativelib" />
        <xs:element ref="extension" />
        <xs:element ref="property" />
        <xs:element ref="package" />
      </xs:choice>
      <xs:attribute name="locale" type="xs:string" use="optional" />
      <xs:attribute name="arch" type="xs:string" use="optional" />
      <xs:attribute name="os" type="xs:string" use="optional" />
    </xs:complexType>
  </xs:element>

  <xs:element name="security">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="all-permissions" minOccurs="0" />
        <xs:element ref="j2ee-application-client-permissions"
minOccurs="0" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="shortcut">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="desktop" minOccurs="0" />
        <xs:element ref="menu" minOccurs="0" />
      </xs:sequence>
      <xs:attribute name="online" use="optional" default="true">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="true" />
            <xs:enumeration value="false" />
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

  <xs:element name="title">
    <xs:complexType mixed="true" />
  </xs:element>

  <xs:element name="update">
    <xs:complexType>
      <xs:attribute name="check" use="optional" default="timeout">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="always" />
            <xs:enumeration value="timeout" />
            <xs:enumeration value="background" />
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="policy" use="optional" default="always">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="always" />
            <xs:enumeration value="prompt-update" />
            <xs:enumeration value="prompt-run" />
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

  <xs:element name="vendor">
    <xs:complexType mixed="true" />
  </xs:element>

</xs:schema>

--------------------------------------------------------------------------- ----------

<?xml version="1.0" encoding="utf-8"?>

<!-- Do not edit! last regenerated 2008-03-27 07:15 PDT by
ReplicatorSender -->
<jnlp spec="6.0+" codebase="http://mindprod.com/replicator"
href="replicatorreceiverwebsite.jnlp" version="9.8">
  <information>
    <title>The Replicator 9.8 via website</title>

    <vendor>Canadian Mind Products</vendor>
    <homepage href="webstart/replicator.html" />

    <description>Replicates files via website. Also keeps them up to
date efficiently.</description>
    <description kind="short">Replicates files via
website.</description>
    <description kind="one-line">Replicates files via
website.</description>
    <description kind="tooltip">the Replicator</description>
    <!-- relative to codebase, need copy in same dir as jar, and jnlp
file. -->
    <icon href="replicatoricon64.png" width="64" height="64"
kind="default" />
    <icon href="replicatorsplash.png" width="128" height="128"
kind="splash" />
    <!-- online only -->
    <!-- create desktop shortcut to run the Replicator -->
    <shortcut online="true">
      <desktop />
      <menu submenu="The Replicator" />
    </shortcut>
  </information>

  <security>
    <all-permissions />
  </security>

  <update check="always" policy="always" />

  <resources>
    <!-- requires 1.6 -->
    <!-- Sun JVM -->
    <java version="1.6.0_05"
href="http://java.sun.com/products/autodl/j2se" java-vm-args="-ea"
initial-heap-size="128m" max-heap-size="512m" />
    <java version="1.6+"
href="http://java.sun.com/products/autodl/j2se" java-vm-args="-ea"
initial-heap-size="128m" max-heap-size="512m" />
    <!-- any vendor -->
    <java version="1.6+" java-vm-args="-ea" initial-heap-size="128m"
max-heap-size="512m" />

    <!-- application code, download jar before we start. -->
    <jar href="replicator.jar" main="true" download="eager" />

    <!-- set -D system properties -->
    <property name="VIA" value="website" />
    <property name="PROJECT_NAME" value="Mindprod.com" />
    <property name="UNIQUE_PROJECT_NAME"
value="com.mindprod.replicator" />
    <property name="SUGGESTED_RECEIVER_BASE_DIR" value="C:\mindprod"
/>
    <property name="SUGGESTED_RECEIVER_ZIP_STAGING_DIR"
value="C:\mpstaging" />
    <property name="WEBSITE_ZIP_URL"
value="http://mindprod.com/replicator" />
    <property name="SUGGESTED_LAN_ZIP_URL"
value="http://mindprod.com/replicator" />
    <property name="KEEP_ZIPS" value="false" />
    <property name="UNPACK_ZIPS" value="true" />
    <property name="AUTHENTICATION" value="none" />
    <property name="DEBUGGING" value="true" />
  </resources>

  <!-- application class with main method -->
  <application-desc main-class="com.mindprod.replicator.Replicator" />

</jnlp>

--------------------------------------------------------------------------- -----------------------------------

// validating a JNLP document with an XSD schema

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import javax.xml.XMLConstants;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
  * Validate on JNLP file using the Vampqh JNLP XSD schema
  * Requires a copy of the Vampqh schema "jnlp1-xml-schema.xsd"
version 1.0
  * or "jnlp6-xml-schema.xsd" version 6.0 in the current directory.
  */
public class ValidateJNLP
   {
   /**
    * validate one jnlp file
    *
    * @param args first name of xsd schema,
    * second name of name of the jnlp file to validate,
    * e.g. E:\com\mindprod\affirm\affirm.jnlp
    */
   public static void main ( String[] args )
      {
      try
         {
         // build an XSD-aware SchemaFactory
         SchemaFactory schemaFactory = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI );

         // hook up mindless org.xml.sax.ErrorHandler implementation.
         schemaFactory.setErrorHandler( new JNLPErrorHandler() );

         // get the custom xsd schema describing the required format
for my XML files.
         Schema schemaXSD = schemaFactory.newSchema( new File (
args[0] ) );

         // Create a Validator capable of validating JNLP files
according to to the custom schema.
         Validator validator = schemaXSD.newValidator();

         // Validate the JNLP file that is supposed to conform to the
custom schema
         DocumentBuilder parser =
DocumentBuilderFactory.newInstance().newDocumentBuilder();

         // parse the JNLP file on the command line purely as XML and
get a DOM tree represenation.
         Document document = parser.parse( new File( args[1] ));

         // parse the JNLP tree against the stricter XSD schema
         validator.validate( new DOMSource( document ) );
         }
      catch ( Exception e )
         {
         e.printStackTrace();
         }
      } // end main

   } // end ValidateJNLP

class JNLPErrorHandler implements ErrorHandler
   {
   /**
    * default contstructor
    */
   public JNLPErrorHandler()
      {
      }

   /**
    * Receive notification of a warning.
    *
    * <p>SAX parsers will use this method to report conditions that
    * are not errors or fatal errors as defined by the XML
    * recommendation.  The default behaviour is to take no
    * action.</p>
    *
    * <p>The SAX parser must continue to provide normal parsing events
    * after invoking this method: it should still be possible for the
    * application to process the document through to the end.</p>
    *
    * <p>Filters may use this method to report other, non-XML warnings
    * as well.</p>
    *
    * @param exception The warning information encapsulated in a
    *                  SAX parse exception.
    * @exception org.xml.sax.SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see org.xml.sax.SAXParseException
    */
   public void warning (SAXParseException exception)
   throws SAXException
   {
      System.err.println( exception );
   }

   /**
    * Receive notification of a recoverable error.
    *
    * <p>This corresponds to the definition of "error" in section 1.2
    * of the W3C XML 1.0 Recommendation.  For example, a validating
    * parser would use this callback to report the violation of a
    * validity constraint.  The default behaviour is to take no
    * action.</p>
    *
    * <p>The SAX parser must continue to provide normal parsing
    * events after invoking this method: it should still be possible
    * for the application to process the document through to the end.
    * If the application cannot do so, then the parser should report
    * a fatal error even if the XML recommendation does not require
    * it to do so.</p>
    *
    * <p>Filters may use this method to report other, non-XML errors
    * as well.</p>
    *
    * @param exception The error information encapsulated in a
    *                  SAX parse exception.
    * @exception org.xml.sax.SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see org.xml.sax.SAXParseException
    */
   public  void error (SAXParseException exception)
   throws SAXException
   {
      System.err.println( exception );
   }

   /**
    * Receive notification of a non-recoverable error.
    *
    * <p><strong>There is an apparent contradiction between the
    * documentation for this method and the documentation for {@link
    * org.xml.sax.ContentHandler#endDocument}.  Until this ambiguity
    * is resolved in a future major release, clients should make no
    * assumptions about whether endDocument() will or will not be
    * invoked when the parser has reported a fatalError() or thrown
    * an exception.</strong></p>
    *
    * <p>This corresponds to the definition of "fatal error" in
    * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
    * parser would use this callback to report the violation of a
    * well-formedness constraint.</p>
    *
    * <p>The application must assume that the document is unusable
    * after the parser has invoked this method, and should continue
    * (if at all) only for the sake of collecting additional error
    * messages: in fact, SAX parsers are free to stop reporting any
    * other events once this method has been invoked.</p>
    *
    * @param exception The error information encapsulated in a
    *                  SAX parse exception.
    * @exception org.xml.sax.SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see org.xml.sax.SAXParseException
    */
   public  void fatalError (SAXParseException exception)
   throws SAXException
   {
      System.err.println( exception );
   }

   } // end JNLPErrorHandler

Sure, I'll have a look. However, I'm curious - why are you converting
the DTD file, which is Sun's official definition of the JNLP schema,
to an XSD schema? It's possible to validate documents against DTD
schemas just fine, using most tools...

-o
 
R

Roedy Green

Sure, I'll have a look. However, I'm curious - why are you converting
the DTD file, which is Sun's official definition of the JNLP schema,
to an XSD schema? It's possible to validate documents against DTD
schemas just fine, using most tools...

1. xsd is easier to understand.

2. I don't know how to use a DTD to validate. I do know how to use an
XSD.

3. I thought it would a trivial problem to solve. It is bad enough
asking for help without giving up on the project entirely. I wanted
this for to illustrate the use of XSD at
http://mindprod.com/jgloss/xsd.html

4. I want to know a bit more about XSD.
 
O

Owen Jacobson

I took Sun's DTD to validate JNLP 6.0 athttp://java.sun.com/dtd/JNLP-6.0.dtd
and ran in through the DTD->XSD converter athttp://www.hitsw.com/xml_utilites/

I then I tried validating one of my JNLP files. It seems to think you
are not supposed to nest <java inside <resources which Sun's example
says is kosher.

Presumably the problem is the DTD->XSD conversion process was flawed.
The XSD is baffling. It seems to show both <java inside <resources and
<resources inside <java.

<?xml version="1.0" encoding="utf-8"?>

<!-- Do not edit! last regenerated 2008-03-27 07:15 PDT by
ReplicatorSender -->
<jnlp spec="6.0+" codebase="http://mindprod.com/replicator"
href="replicatorreceiverwebsite.jnlp" version="9.8">
<information>
<title>The Replicator 9.8 via website</title>

<vendor>Canadian Mind Products</vendor>
<homepage href="webstart/replicator.html" />

<description>Replicates files via website. Also keeps them up to
date efficiently.</description>
<description kind="short">Replicates files via
website.</description>
<description kind="one-line">Replicates files via
website.</description>
<description kind="tooltip">the Replicator</description>
<!-- relative to codebase, need copy in same dir as jar, and jnlp
file. -->
<icon href="replicatoricon64.png" width="64" height="64"
kind="default" />
<icon href="replicatorsplash.png" width="128" height="128"
kind="splash" />
<!-- online only -->
<!-- create desktop shortcut to run the Replicator -->
<shortcut online="true">
<desktop />
<menu submenu="The Replicator" />
</shortcut>
</information>

<security>
<all-permissions />
</security>

<update check="always" policy="always" />

<resources>
<!-- requires 1.6 -->
<!-- Sun JVM -->
<java version="1.6.0_05"
href="http://java.sun.com/products/autodl/j2se" java-vm-args="-ea"
initial-heap-size="128m" max-heap-size="512m" />
<java version="1.6+"
href="http://java.sun.com/products/autodl/j2se" java-vm-args="-ea"
initial-heap-size="128m" max-heap-size="512m" />
<!-- any vendor -->
<java version="1.6+" java-vm-args="-ea" initial-heap-size="128m"
max-heap-size="512m" />

<!-- application code, download jar before we start. -->
<jar href="replicator.jar" main="true" download="eager" />

<!-- set -D system properties -->
<property name="VIA" value="website" />
<property name="PROJECT_NAME" value="Mindprod.com" />
<property name="UNIQUE_PROJECT_NAME"
value="com.mindprod.replicator" />
<property name="SUGGESTED_RECEIVER_BASE_DIR" value="C:\mindprod"
/>
<property name="SUGGESTED_RECEIVER_ZIP_STAGING_DIR"
value="C:\mpstaging" />
<property name="WEBSITE_ZIP_URL"
value="http://mindprod.com/replicator" />
<property name="SUGGESTED_LAN_ZIP_URL"
value="http://mindprod.com/replicator" />
<property name="KEEP_ZIPS" value="false" />
<property name="UNPACK_ZIPS" value="true" />
<property name="AUTHENTICATION" value="none" />
<property name="DEBUGGING" value="true" />
</resources>

<!-- application class with main method -->
<application-desc main-class="com.mindprod.replicator.Replicator" />

</jnlp>

I've uploaded this document, plus the appropriate <!DOCTYPE directive,
to my own server at <http://bast.lionsanctuary.net/~owen/jnlp> and
used
the W3C markup validator - which determined that the document is
invalid per the DTD. Here is its output:

Line 204, Column 16: character ">" invalid: only delimiter "-",
number, "ANY", "CDATA", "EMPTY", "O", "RCDATA" and parameter
separators allowed. ...

Line 629, Column 29: name start character invalid: only delimiter
"&", delimiter "|", delimiter ",", delimiter ")" and token
separators are allowed. ...

Line 31, Column 27: element "shortcut" undefined. <shortcut
online="true">

You have used the element named above in your document, but the
document type you are using does not define an element of that
name.

Line 39, Column 42: element "update" undefined. <update
check="always" policy="always" />

You have used the element named above in your document, but the
document type you are using does not define an element of that
name.

I believe the first two errors are related to parsing problems with
the
DTD - the XML document itself is not 204 lines long, and the error
message relates to the validity of a DTD, not to a document. The Sun
DTD
contains errors in the definitions of the 'update' and 'shortcut'
elements, and this should be reported to Sun as a bug:

<update> should be <!ELEMENT update EMPTY>
<shortcut> should be <!ELEMENT shortcut (desktop?, menu?)>

I uploaded a mutilated copy of the DTD alongside the document (which
is
what you see if you look at the document now) that contains fixes for
these bugs. This is sufficient to allow DTD-based validation to
complete:

<http://validator.w3.org/check?uri=http:/
%2Fbast.lionsanctuary.net%2F%7Eowen%2Fjnlp&charset=%28detect
+automatically%29&doctype=Inline&group=0>

More to come...
-o
 
R

Roedy Green

I then I tried validating one of my JNLP files. It seems to think you
are not supposed to nest <java inside <resources which Sun's example
says is kosher.

Success. See http://mindprod.com/jgloss/jnlp.html
for all the pieces including DTDs, XSDs, and program for JNLP 1.0, 5.0
and 6.0.

I used Stylus studio to generate the XSD instead of the online
service, and made some minor tweaks.

With this framework the XSDs could be refined to catch more errors.
 
A

Andrew Thompson

I took Sun's DTD to validate JNLP 6.0 at http://java.sun.com/dtd/JNLP-6.0.dtd
and ran in through the DTD->XSD converter at http://www.hitsw.com/xml_utilites/

Just before 24th July 2007, you started
a thread titled "JNLP xsd schema".

On 24th July, 2007, Piotr Kobzda pointed
out that the 6.0 JNLP DTD was invalid.
<http://coding.derkeiler.com/Archive/Java/comp.lang.java.programmer/
2007-07/msg02115.html>

I raised a bug report against the 6.0 JNLP DTD.
<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6656846>

This bug was addressed, and Andy Herrick
assured me that the DTD in the spec. had
been updated (I have not checked that)
and that he had asked the web folks to
update the online version.

Your experience suggests that the online
version is still invalid.

Conclusion. GIGO.
 
R

Roedy Green

Conclusion. GIGO.

No garbage in. I have that documented on my website, (you even get a
an acknowledgement) and I corrected the DTD before converting to XSD.
 
A

Andrew Thompson

No garbage in.  
Good.

..I have that documented on my website, ..

Unforunately my bandwidth is very limited
at the moment and I have to make some drastic*
decisions about what I can download.

(* Many of the extensive MindProd pages time
out before completely downloading. That is
probably more a comment on my OS component,
and perhaps I should look into a browser that
lets me *set* the timeout.)
..(you even get a an acknowledgement)

(grins) Thanks. But I hope you mentioned
Piotr K. *more* prominently. Most of what I
(think I) know about validation, came directly
from him.
..and I corrected the DTD before converting to XSD.

Excellent work.
 
R

Roedy Green

(grins) Thanks. But I hope you mentioned
Piotr K. *more* prominently. Most of what I
(think I) know about validation, came directly
from him.

Yes, I did. And I post the corrected DTD.

I get spoiled by either local viewing or viewing via high speed
internet from server only just a short ferry ride away.

I did not realise people were having trouble with timeouts. I should
have a look into splitting up the longest pages.

If you do a lot of viewing on my site, you could use The Replicator to
maintain a local mirror copy for you.
see http://mindprod.com/jgloss/replicator.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top