media @ VU
[] readme course preface I 1 2 II 3 4 III 5 6 7 IV 8 9 10 V 11 12 afterthoughts appendix references examples resources

talk show tell print

vr-x3d-unwrap.xsl


  <?xml version='1.0'?>
  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                  xmlns:saxon="http://icl.com/saxon" saxon:trace="no">
  
  <!--
    <head>
     <meta name="filename"    content="X3dUnwrap.xsl" />
     <meta name="author"      content="Don Brutzman" />
     <meta name="revised"     content="7 December 2001" />
     <meta name="description" content="XSL stylesheet to add x3d-compromise.dtd wrapper tags where needed, remove attributes with default values, pretty-print X3D source, etc." />
     <meta name="url"         content="http://www.web3D.org/TaskGroups/x3d/translation/X3dUnwrap.xsl" />
    </head>
  
  Recommended tool:
  
   SAXON XML Toolkit (and Instant Saxon) from Michael Kay of ICL, users.iclway.co.uk/mhkay/saxon
  
  Can also be used with Apache server.  Point of contact:  Jeff Sonstein.
  
  Problems:
  
  DTD fragment at beginning of source file handled OK, but with literals instead of XSL constructs.
    Need to read and retain parameter entities defined in file, if possible.  Future work for XSL.
  Disable output escaping and use apostrophes/quotes for attributes containing quotes/apostrophes.
  
  -->  
  
  <!--        XSL names spaces are in transition!  Tools are slow to catch up.  
      ***        Edit the topmost stylesheet tag on line 2 of this file to match your XSL tool. ***
          W3C:             
          Saxon:           <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
          IBM XSLEditor:   <xsl:stylesheet xmlns:xsl='http://www.w3.org/XSL/Transform/1.0'>
          IE 5:            <xsl:stylesheet xmlns:xsl='http://www.w3.org/TR/WD-xsl'>
          XT:              <xsl:stylesheet xmlns:xsl='http://www.w3.org/XSL/Transform'>
  -->
  
  <xsl:preserve-space elements="Script" />
  <xsl:strip-space elements="*" />
  <xsl:output method="xml" encoding="utf-8" indent="yes" media-type="text/xml" omit-xml-declaration="no" />
  <!-- xsl:output attributes for DOCTYPE (handled via text output by root tag)
          doctype-public="http://www.web3D.org/TaskGroups/x3d/translation/x3d-compromise.dtd"
          doctype-system="file: 
C:/www.web3D.org/TaskGroups/x3d/translation/x3d-compromise.dtd"

or doctype-public="http://www.web3D.org/TaskGroups/x3d/translation/x3d-compact.dtd" doctype-system="file:
C:/www.web3D.org/TaskGroups/x3d/translation/x3d-compact.dtd"

cdata-section-elements="@string" --> <!-- ****** root: start of file ****** --> <xsl:template match="/"> <xsl:text disable-output-escaping="yes">&#10;&lt;!DOCTYPE X3D PUBLIC&#10;</xsl:text> <xsl:text disable-output-escaping="yes"> "http://www.web3D.org/TaskGroups/x3d/translation/x3d-compact.dtd" <xsl:text disable-output-escaping="yes"> "/www.web3D.org/TaskGroups/x3d/translation/x3d-compact.dtd" [ <xsl:text disable-output-escaping="yes"> <!ENTITY % BaseLineProfile "INCLUDE"> <xsl:text disable-output-escaping="yes"> <!ENTITY % CoreProfile "IGNORE"> <xsl:text disable-output-escaping="yes"> <!ENTITY % DisJavaVrmlProfile "INCLUDE"> <xsl:text disable-output-escaping="yes"> <!ENTITY % GeoVrmlProfile "INCLUDE"> <xsl:text disable-output-escaping="yes"> <!ENTITY % HAnimProfile "INCLUDE"> <xsl:text disable-output-escaping="yes">]&gt;&#10;</xsl:text> <xsl:apply-templates/> <xsl:text>&#10;</xsl:text> </xsl:template> <!-- ****** recurse through each of the tree node elements ****** --> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates select="@DEF | @USE | @*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template> <!-- ****** recurse through each of the tree node elements ****** --> <xsl:template match="comment()"> <!-- Xeena (the X3D-Edit engine) is garbling comments, so (otherwise-unnecessary) normalization will ungarble them. --> <xsl:comment><xsl:value-of select="normalize-space(.)"/></xsl:comment> </xsl:template> <!-- ****** children: ignore wrapper tags (since redundant with VRML definitions) ****** --> <xsl:template match="appearance[local-name(..)='Shape'] | children[local-name(..)='Anchor' or local-name(..)='Billboard' or local-name(..)='Collision' or local-name(..)='Group' or local-name(..)='Transform' or local-name(..)='Contour2D' or local-name(..)='CoordinateDeformer' or local-name(..)='EspduTransform' or local-name(..)='GeoInline' or local-name(..)='GeoLocation' or local-name(..)='GeoLOD' or local-name(..)='Humanoid' or local-name(..)='Joint' or local-name(..)='NurbsGroup' or local-name(..)='ReceiverPdu' or local-name(..)='Segment' or local-name(..)='SignalPdu' or local-name(..)='Site' or local-name(..)='TransmitterPdu'] | choice[local-name(..)='Switch'] | color[local-name(..)='ElevationGrid' or local-name(..)='IndexedFaceSet' or local-name(..)='IndexedLineSet' or local-name(..)='PointSet' or local-name(..)='GeoElevationGrid' ] | coord[local-name(..)='IndexedFaceSet' or local-name(..)='IndexedLineSet' or local-name(..)='PointSet'] | fontStyle[local-name(..)='Text'] | geometry[local-name(..)='Shape'] | level[local-name(..)='LOD'] | material[local-name(..)='Appearance'] | normal[local-name(..)='ElevationGrid' or local-name(..)='IndexedFaceSet' or local-name(..)='GeoElevationGrid'] | source[local-name(..)='Sound'] | texCoord[local-name(..)='ElevationGrid' or local-name(..)='IndexedFaceSet' or local-name(..)='GeoElevationGrid' or local-name(..)='NurbsSurface'] | texture[local-name(..)='Appearance'] | textureTransform[local-name(..)='Appearance'] | joints[local-name(..)='Humanoid'] | segments[local-name(..)='Humanoid'] | viewpoints[local-name(..)='Humanoid'] | sites[local-name(..)='Humanoid']"> <xsl:apply-templates select="*"/> </xsl:template> <!-- ****** recurse through each of the attributes ****** --> <xsl:template match="@*"> <!-- eliminate default attribute values, otherwise they will _all_ appear in output --> <!-- this block is used identically in X3dToVrml97.xsl X3dToHtml.xsl X3dUnwrap.xsl and X3dWrap.xsl --> <!-- check values with/without .0 suffix since these are string checks and autogenerated/DOM output might have either --> <!-- do not check ProtoInstances or natively defined nodes, since they might have different user-defined defaults --> <!-- tool-bug workaround: split big boolean queries into pieces to avoid overloading the Xalan/lotusxml query buffer --> <xsl:variable name="notImplicitEvent" select="not(local-name(..)='AudioClip' and (local-name()='duration' or local-name()='isActive')) and not(contains(local-name(..),'Interpolator') and (local-name()='fraction' or local-name()='value')) and not(local-name(..)='Background' and (local-name()='bind' or local-name()='bindTime' or local-name()='isBound')) and not(local-name(..)='CylinderSensor' and (local-name()='isActive' or local-name()='rotation' or local-name()='trackPoint')) and not(local-name(..)='Fog' and (local-name()='bind' or local-name()='bindTime' or local-name()='isBound')) and not(local-name(..)='IndexedLineSet' and local-name()='lineWidth') and not(local-name(..)='NavigationInfo' and (local-name()='bind' or local-name()='bindTime' or local-name()='isBound')) and not(local-name(..)='PointSet' and local-name()='pointSize') and not(local-name(..)='PlaneSensor' and (local-name()='isActive' or local-name()='translation' or local-name()='trackPoint')) and not(local-name(..)='ProximitySensor' and (local-name()='isActive' or local-name()='position' or local-name()='orientation' or local-name()='enterTime' or local-name()='exitTime')) and not(local-name(..)='SphereSensor' and (local-name()='isActive' or local-name()='rotation' or local-name()='trackPoint')) and not(local-name(..)='TimeSensor' and (local-name()='isActive' or local-name()='cycleTime' or local-name()='fraction' or local-name()='time')) and not(local-name(..)='TouchSensor' and (local-name()='isActive' or local-name()='isOver' or local-name()='hitNormal' or local-name()='touchTime' or local-name()='hitPoint' or local-name()='hitTexCoord')) and not(local-name(..)='Viewpoint' and (local-name()='bind' or local-name()='bindTime' or local-name()='isBound' or local-name()='examine'))" /> <xsl:variable name="notDefaultFieldValue1" select="not( local-name()='bboxCenter' and (.='0 0 0' or .='0.0 0.0 0.0')) and not( local-name()='bboxSize' and (.='-1 -1 -1' or .='-1.0 -1.0 -1.0')) and not( local-name(..)='AudioClip' and ((local-name()='loop' and .='false') or (local-name()='pitch' and (.='1' or .='1.0')) or (local-name()='startTime' and (.='0' or .='0.0')) or (local-name()='stopTime' and (.='0 0 0' or .='0.0 0.0 0.0')))) and not( local-name(..)='Background' and local-name()='skyColor' and (.='0 0 0' or .='0.0 0.0 0.0')) and not( local-name(..)='Billboard' and local-name()='axisOfRotation' and (.='0 1 0' or .='0.0 1.0 0.0')) and not( local-name(..)='Box' and local-name()='size' and (.='2 2 2' or .='2.0 2.0 2.0')) and not( local-name(..)='Collision' and local-name()='collide' and .='true') and not( local-name(..)='Cone' and ((local-name()='bottomRadius' and (.='1' or .='1.0')) or (local-name()='height' and (.='2' or .='2.0')) or (local-name()='side' and .='true') or (local-name()='bottom' and .='true'))) and not( local-name(..)='Cylinder' and ((local-name()='height' and (.='2' or .='2.0')) or (local-name()='radius' and (.='1' or .='1.0')) or (local-name()='bottom' and .='true') or (local-name()='side' and .='true') or (local-name()='top' and .='true'))) and not( local-name(..)='CylinderSensor' and ((local-name()='autoOffset' and .='true') or (local-name()='enabled' and .='true') or (local-name()='diskAngle' and .='0.262') or (local-name()='offset' and (.='0' or .='0.0')) or (local-name()='maxAngle' and (.='-1' or .='-1.0')) or (local-name()='minAngle' and (.='0' or .='0.0'))))" /> <xsl:variable name="notDefaultFieldValue2" select="not( local-name(..)='DirectionalLight' and ((local-name()='ambientIntensity' and (.='0' or .='0.0')) or (local-name()='color' and (.='1 1 1' or .='1.0 1.0 1.0')) or (local-name()='direction' and (.='0 0 -1' or .='0.0 0.0 -1.0')) or (local-name()='intensity' and (.='1' or .='1.0')) or (local-name()='on' and .='true'))) and not( local-name(..)='ElevationGrid' and ((local-name()='ccw' and .='true') or (local-name()='colorPerVertex' and .='true') or (local-name()='normalPerVertex' and .='true') or (local-name()='solid' and .='true') or (local-name()='xDimension' and (.='0' or .='0.0')) or (local-name()='xSpacing' and (.='1' or .='1.0')) or (local-name()='zDimension' and (.='0' or .='0.0')) or (local-name()='zSpacing' and (.='1' or .='1.0')) or (local-name()='creaseAngle' and (.='0' or .='0.0')))) and not( local-name(..)='Extrusion' and ((local-name()='beginCap' and .='true') or (local-name()='ccw' and .='true') or (local-name()='convex' and .='true') or (local-name()='endCap' and .='true') or (local-name()='solid' and .='true') or (local-name()='creaseAngle' and (.='0' or .='0.0')) or (local-name()='orientation' and (.='0 0 1 0' or .='0.0 0.0 1.0 0.0')) or (local-name()='scale' and (.='1 1' or .='1.0 1.0')) or (local-name()='crossSection' and .='1 1, 1 -1, -1 -1, -1 1, 1 1') or (local-name()='spine' and .='0 0 0, 0 1 0')))" /> <xsl:variable name="notDefaultFieldValue3" select="not( local-name(..)='Fog' and ((local-name()='color' and (.='1 1 1' or .='1.0 1.0 1.0')) or (local-name()='visibilityRange' and (.='0' or .='0.0')) or (local-name()='fogType' and .='"LINEAR"'))) and not( local-name(..)='FontStyle' and ((local-name()='horizontal' and .='true') or (local-name()='leftToRight' and .='true') or (local-name()='topToBottom' and .='true') or (local-name()='size' and (.='1' or .='1.0')) or (local-name()='spacing' and (.='1' or .='1.0')) or (local-name()='family' and .='"SERIF"') or (local-name()='justify' and .='"BEGIN"') or (local-name()='style' and .='PLAIN'))) and not( local-name(..)='ImageTexture' and ((local-name()='repeatS' and .='true') or (local-name()='repeatT' and .='true'))) and not( local-name(..)='IndexedFaceSet' and ((local-name()='ccw' and .='true') or (local-name()='colorPerVertex' and .='true') or (local-name()='convex' and .='true') or (local-name()='normalPerVertex' and .='true') or (local-name()='solid' and .='true') or (local-name()='creaseAngle' and (.='0' or .='0.0')))) and not( local-name(..)='IndexedLineSet' and local-name()='colorPerVertex' and .='true') and not( local-name(..)='LOD ' and local-name()='center' and (.='0 0 0' or .='0.0 0.0 0.0')) and not( local-name(..)='Material' and ((local-name()='ambientIntensity' and .='0.2') or (local-name()='diffuseColor' and .='0.8 0.8 0.8') or (local-name()='emissiveColor' and (.='0 0 0' or .='0.0 0.0 0.0')) or (local-name()='shininess' and .='0.2') or (local-name()='specularColor' and (.='0 0 0' or .='0.0 0.0 0.0')) or (local-name()='transparency' and (.='0' or .='0.0'))))" /> <xsl:variable name="notDefaultFieldValue4" select="not( local-name(..)='MovieTexture' and ((local-name()='loop' and .='false') or (local-name()='speed' and (.='1' or .='1.0')) or (local-name()='startTime' and (.='0' or .='0.0')) or (local-name()='stopTime' and (.='0' or .='0.0')) or (local-name()='repeatS' and .='true') or (local-name()='repeatT' and .='true'))) and not( local-name(..)='NavigationInfo' and ((local-name()='avatarSize' and .='0.25 1.6 0.75') or (local-name()='headlight' and .='true') or (local-name()='speed' and (.='1' or .='1.0')) or (local-name()='visibilityLimit' and (.='0' or .='0.0')))) and not( local-name(..)='PixelTexture' and ((local-name()='repeatS' and .='true') or (local-name()='repeatT' and .='true') or (local-name()='image' and (.='0 0 0' or .='0.0 0.0 0.0')))) and not( local-name(..)='PlaneSensor' and ((local-name()='autoOffset' and .='true') or (local-name()='enabled' and .='true') or (local-name()='maxPosition' and (.='-1 -1' or .='-1.0 -1.0')) or (local-name()='minPosition' and (.='0 0' or .='0.0 0.0')) or (local-name()='offset' and (.='0 0 0' or .='0.0 0.0 0.0')))) and not( local-name(..)='PointLight' and ((local-name()='ambientIntensity' and (.='0' or .='0.0'))or (local-name()='attenuation' and (.='1 0 0' or .='1.0 0.0 0.0')) or (local-name()='color' and (.='1 1 1' or .='1.0 1.0 1.0')) or (local-name()='intensity' and (.='1' or .='1.0')) or (local-name()='location' and (.='0 0 0' or .='0.0 0.0 0.0')) or (local-name()='on' and .='true') or (local-name()='radius' and (.='100' or .='100.0'))))" /> <xsl:variable name="notDefaultFieldValue5" select="not( local-name(..)='ProximitySensor' and ((local-name()='center' and (.='0 0 0' or .='0.0 0.0 0.0')) or (local-name()='size' and (.='0 0 0' or .='0.0 0.0 0.0')) or (local-name()='enabled' and .='true'))) and not( local-name(..)='Script' and ((local-name()='directOutput' and .='false') or (local-name()='mustEvaluate' and .='false'))) and not( local-name(..)='Sound' and ((local-name()='direction' and (.='0 0 1' or .='0.0 0.0 1.0')) or (local-name()='intensity' and (.='1' or .='1.0')) or (local-name()='location' and (.='0 0 0' or .='0.0 0.0 0.0')) or (local-name()='priority' and (.='0' or .='0.0')) or (local-name()='maxBack' and (.='10' or .='10.0')) or (local-name()='maxFront' and (.='10' or .='10.0')) or (local-name()='minBack' and (.='1' or .='1.0')) or (local-name()='minFront' and (.='1' or .='1.0')) or (local-name()='spatialize' and .='true'))) and not( local-name(..)='Sphere' and local-name()='radius' and (.='1' or .='1.0')) and not( local-name(..)='SphereSensor' and ((local-name()='autoOffset' and .='true') or (local-name()='enabled' and .='true') or (local-name()='offset' and (.='0 1 0 0' or .='0.0 1.0 0.0 0.0'))))" /> <xsl:variable name="notDefaultFieldValue6" select="not( parent::SpotLight and ((local-name()='ambientIntensity' and (.='0' or .='0.0')) or (local-name()='attenuation' and (.='1 0 0' or .='1.0 0.0 0.0')) or (local-name()='beamwidth' and .='1.570796') or (local-name()='color' and (.='1 1 1' or .='1.0 1.0 1.0')) or (local-name()='cutOffAngle' and .='0.785398') or (local-name()='direction' and (.='0 0 -1' or .='0.0 0.0 -1.0')) or (local-name()='intensity' and (.='1' or .='1.0')) or (local-name()='location' and (.='0 0 0' or .='0.0 0.0 0.0')) or (local-name()='on' and .='true') or (local-name()='radius' and (.='100' or .='100.0')))) and not( local-name(..)='Switch' and local-name()='whichChoice' and (.='-1' or .='-1.0')) and not( local-name(..)='Text' and local-name()='maxExtent' and (.='0' or .='0.0')) and not( local-name(..)='TextureTransform' and ((local-name()='center' and (.='0 0' or .='0.0 0.0')) or (local-name()='rotation' and (.='0' or .='0.0')) or (local-name()='scale ' and (.='1 1' or .='1.0 1.0')) or (local-name()='translation' and (.='0 0' or .='0.0 0.0')))) and not( local-name(..)='Switch' and local-name()='whichChoice' and (.='-1' or .='-1.0'))" /> <xsl:variable name="notDefaultFieldValue7" select="not( local-name(..)='TimeSensor' and ((local-name()='cycleInterval' and (.='1' or .='1.0')) or (local-name()='enabled' and .='true') or (local-name()='startTime' and (.='0' or .='0.0')) or (local-name()='stopTime' and (.='0' or .='0.0')) or (local-name()='loop' and .='false'))) and not( local-name(..)='TouchSensor' and local-name()='enabled' and .='true') and not( local-name(..)='Transform' and ((local-name()='center' and (.='0 0 0' or .='0.0 0.0 0.0')) or (local-name()='rotation' and (.='0 0 1 0' or .='0.0 0.0 1.0 0.0')) or (local-name()='scale' and (.='1 1 1' or .='1.0 1.0 1.0')) or (local-name()='scaleOrientation' and (.='0 0 1 0' or .='0.0 0.0 1.0 0.0')) or (local-name()='translation' and (.='0 0 0' or .='0.0 0.0 0.0')))) and not( local-name(..)='Viewpoint' and ((local-name()='fieldOfView' and .='0.785398') or (local-name()='jump' and .='true') or (local-name()='orientation' and (.='0 0 1 0' or .='0.0 0.0 1.0 0.0')) or (local-name()='position' and (.='0 0 10' or .='0.0 0.0 10.0')))) and not( local-name(..)='VisibilitySensor' and ((local-name()='center' and (.='0 0 0' or .='0.0 0.0 0.0')) or (local-name()='enabled' and .='true') or (local-name()='size' and (.='0 0 0' or .='0.0 0.0 0.0'))))" /> <xsl:if test=" notImplicitEvent and notDefaultFieldValue1 and notDefaultFieldValue2 and notDefaultFieldValue3 and notDefaultFieldValue4 and notDefaultFieldValue5 and notDefaultFieldValue6 and notDefaultFieldValue7 and not((local-name(..)='Script' or local-name(..)='field') and (local-name()='xml:space' or local-name()='space'))" > <!-- valid field found by the preceding checks, now output accordingly --> <xsl:copy /> </xsl:if> </xsl:template> <!-- ****** proxy field => Proxy node ****** --> <xsl:template match="proxy"> <xsl:element name="proxy"> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="*"/> </xsl:element> </xsl:template> <xsl:template match="Proxy"> <xsl:element name="proxy"> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="*"/> </xsl:element> </xsl:template> <!-- ****** Script node CDATA content ****** --> <xsl:template match="Script"> <xsl:copy> <xsl:apply-templates select="@name | @DEF | @*"/> <xsl:apply-templates select="field | comment()"/> <xsl:if test="text()"> <!-- contained content for Script node is scripting code, output as url --> <xsl:if test="@url"><xsl:text># XSL-translation warning: found url pointing to external script code and also contained code in CDATA section&#10;</xsl:text></xsl:if> <!-- CosmoPlayer url must start with javascript: or else it fails. Update to handle other script language source when supported. --> <xsl:text>&#10;</xsl:text> <xsl:text disable-output-escaping="yes">&lt;!</xsl:text> <xsl:text>[CDATA[javascript:</xsl:text> <xsl:for-each select="text()"> <xsl:choose> <xsl:when test="substring-before(.,'javascript:') or 'j'=substring-before(.,'avascript:')"></xsl:when> <xsl:otherwise><xsl:value-of select="." disable-output-escaping="yes" /></xsl:otherwise> </xsl:choose> </xsl:for-each> <xsl:text>&#10;]</xsl:text> <xsl:text disable-output-escaping="yes">]&gt;&#10;</xsl:text> </xsl:if> </xsl:copy> </xsl:template> <!-- ****** tag renames !!! (get rid of these when content converted to avoid future name collisions with user nodes) ****** --> <!-- defaultValue changed to fieldValue --> <xsl:template match="defaultValue[local-name(..)='Script' or local-name(..)='ProtoInstance']"> <xsl:element name="fieldValue"> <xsl:apply-templates select="@name | @*"/> <xsl:apply-templates select="*"/> </xsl:element> </xsl:template> <!-- Header changed to head --> <xsl:template match="Header"> <xsl:element name="head"> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="*"/> </xsl:element> </xsl:template> <!-- ROUTE --> <xsl:template match="Route[local-name(..)='Scene']"> <!-- match Route and rename ROUTE --> <xsl:element name="ROUTE"> <xsl:apply-templates select="@*"/> </xsl:element> </xsl:template> </xsl:stylesheet>

[] readme course preface I 1 2 II 3 4 III 5 6 7 IV 8 9 10 V 11 12 afterthoughts appendix references examples resources

(C) A. Eliëns 9/8/2006

You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.