<name>generic-color</name>
<class-name>GenericColor</class-name>
<datatype>ColorType</datatype>
- <datatype-conversion type="String" varname="strval">
+ <datatype-conversion from-type="String" varname="strval">
new ColorType(strval)</datatype-conversion>
</property>
<property type="generic">
<datatype>Number</datatype>
<keyword-equiv match="auto" eval="true">0</keyword-equiv>
<keyword-equiv match="always" eval="true">-1</keyword-equiv>
-<!-- <compound>
+<!-- <compound>
<subproperty>
<name>within-page</name>
<datatype>Number</datatype>
<class-name>GenericCondLength</class-name>
<datatype>CondLength</datatype>
<compound>
- <subproperty>
+ <subproperty set-by-shorthand="true">
<name>length</name>
<datatype>Length</datatype>
</subproperty>
<class-name>GenericCondPadding</class-name>
<use-generic>GenericCondLength</use-generic>
<inherited>false</inherited>
- <default>0pt</default>
+ <default subproperty="length">0pt</default>
</property>
<property type="generic">
<name>padding-template</name>
<inherited>false</inherited>
<default>0pt</default>
</property>
-<!-- Before and After border width props -->
+
+<!-- Before, After, Start, End border width props -->
+<!-- CondLength, but adds keyword values both to the "shorthand" setting
+ and to the length component. So we redefine the components here,
+ rather than doing a "use-generic" on GenericCondLength.
+-->
<property type="generic">
<name>border-cond-width-template</name>
<class-name>GenericCondBorderWidth</class-name>
- <use-generic>GenericCondLength</use-generic>
<keyword-equiv match="thin" eval="true">0.5pt</keyword-equiv>
<keyword-equiv match="medium" eval="true">1pt</keyword-equiv>
<keyword-equiv match="thick" eval="true">2pt</keyword-equiv>
<inherited>false</inherited>
- <default>0pt</default>
+ <datatype>CondLength</datatype>
+ <compound>
+ <subproperty set-by-shorthand="true">
+ <name>length</name>
+ <datatype>Length</datatype>
+ <keyword-equiv match="thin" eval="true">0.5pt</keyword-equiv>
+ <keyword-equiv match="medium" eval="true">1pt</keyword-equiv>
+ <keyword-equiv match="thick" eval="true">2pt</keyword-equiv>
+ <default>medium</default>
+ </subproperty>
+ <subproperty>
+ <name>conditionality</name>
+ <datatype>String</datatype> <!-- NCName or Enum ??? -->
+ </subproperty>
+ </compound>
</property>
-<!-- Start and End border width, all "absolute" borderwidth props -->
+<!-- Left, Right, Top, Bottom borderwidth props -->
<property type="generic">
<name>border-width-template</name>
<class-name>GenericBorderWidth</class-name>
<class-name>GenericSpace</class-name>
<inherited>false</inherited>
<datatype>Space</datatype>
- <default>0pt</default>
<compound>
- <subproperty>
+ <subproperty set-by-shorthand="true">
<name>minimum</name>
<datatype>Length</datatype>
+ <default>0pt</default>
</subproperty>
- <subproperty>
+ <subproperty set-by-shorthand="true">
<name>optimum</name>
<datatype>Length</datatype>
+ <default>0pt</default>
</subproperty>
- <subproperty>
+ <subproperty set-by-shorthand="true">
<name>maximum</name>
<datatype>Length</datatype>
+ <default>0pt</default>
</subproperty>
<subproperty>
<name>precedence</name>
<datatype>Number</datatype>
+ <default>0</default>
</subproperty>
<subproperty>
<name>conditionality</name>
<datatype>String</datatype> <!-- NCName or Enum ??? -->
+ <default>discard</default>
</subproperty>
</compound>
</property>
<datatype>Length</datatype>
<default>12pt</default>
<!-- percent refers to inherited font size -->
- <percent-ok base="INH-FONTSIZE"></percent-ok>
+ <percent-ok base="INH_FONTSIZE"/>
</property>
<property>
<name>start-indent</name>
<datatype>Length</datatype>
<default contextdep="true">normal</default>
<keyword-equiv match="normal" eval="true">1.2em</keyword-equiv>
- <datatype-conversion type="Number" varname="numval">
+ <datatype-conversion from-type="Number" varname="numval">
new PercentLength(numval.doubleValue(),
getPercentBase(fo,propertyList))</datatype-conversion>
<!-- percent refers to font size -->
- <percent-ok base="FONTSIZE"></percent-ok>
+ <percent-ok base="FONTSIZE"/>
</property>
<property>
<name>text-indent</name>
<property>
<name>padding-before</name>
<use-generic>GenericCondPadding</use-generic>
+ <default subproperty="conditionality">retain</default>
</property>
<property>
<name>padding-after</name>
<use-generic>GenericCondPadding</use-generic>
+ <default subproperty="conditionality">retain</default>
</property>
<property>
<name>padding-start</name>
- <use-generic>GenericPadding</use-generic>
+ <use-generic>GenericCondPadding</use-generic>
+ <default subproperty="conditionality">discard</default>
</property>
<property>
<name>padding-end</name>
- <use-generic>GenericPadding</use-generic>
+ <use-generic>GenericCondPadding</use-generic>
+ <default subproperty="conditionality">discard</default>
</property>
<property>
<name>padding-top</name>
<property>
<name>border-before-width</name>
<use-generic>GenericCondBorderWidth</use-generic>
+ <default subproperty="conditionality">retain</default>
</property>
<property>
<name>border-after-color</name>
<property>
<name>border-after-width</name>
<use-generic>GenericCondBorderWidth</use-generic>
+ <default subproperty="conditionality">retain</default>
</property>
<property>
<name>border-start-color</name>
</property>
<property>
<name>border-start-width</name>
- <use-generic>GenericBorderWidth</use-generic>
+ <use-generic>GenericCondBorderWidth</use-generic>
+ <default subproperty="conditionality">discard</default>
</property>
<property>
<name>border-end-color</name>
</property>
<property>
<name>border-end-width</name>
- <use-generic>GenericBorderWidth</use-generic>
+ <use-generic>GenericCondBorderWidth</use-generic>
+ <default subproperty="conditionality">discard</default>
</property>
<property>
<name>border-top-color</name>
<inherited>false</inherited>
<datatype>Length</datatype>
<auto-ok/>
- <percent-ok base="CONTAINING-BOX"></percent-ok>
+ <percent-ok base="CONTAINING_BOX"/>
<default>auto</default>
</property>
<property>
<property>
<name>leader-length</name>
- <class-name>LeaderLength</class-name>
<inherited>true</inherited>
<datatype>LengthRange</datatype>
- <default>12.0pt</default>
+ <percent-ok base="CONTAINING_BOX"/>
<compound>
- <subproperty>
+ <subproperty set-by-shorthand="true">
<name>minimum</name>
<datatype>Length</datatype>
+ <default>0pt</default>
+ <percent-ok base="CONTAINING_BOX"/>
</subproperty>
- <subproperty>
+ <subproperty set-by-shorthand="true">
<name>optimum</name>
<datatype>Length</datatype>
+ <default>12.0pt</default>
+ <percent-ok base="CONTAINING_BOX"/>
</subproperty>
- <subproperty>
+ <subproperty set-by-shorthand="true">
<name>maximum</name>
<datatype>Length</datatype>
+ <default contextdep="true">100%</default>
+ <percent-ok base="CONTAINING_BOX"/>
</subproperty>
</compound>
-<!-- <percent-ok base="CONTAINING-BOX"></percent-ok>
- <datatype-conversion type="Length" varname="lenval">
- new LengthRange(lenval)</datatype-conversion> -->
</property>
<property>
<datatype>Length</datatype>
<default contextdep="true">use-font-metrics</default>
<keyword-equiv match="use-font-metrics" eval="true">0pt</keyword-equiv>
- <percent-ok base="CONTAINING-BOX"/>
+ <percent-ok base="CONTAINING_BOX"/>
+
</property>
<property>
<default>1</default>
</property>
-
<property>
<name>region-name</name>
<class-name>RegionName</class-name>
<default></default>
</property>
-
<property>
<name>hyphenate</name>
<class-name>Hyphenate</class-name>
<xsl:output method="text" />
+
+<!-- Content of element is code to calculate the base length -->
+<xsl:template match="percent-ok">
+ /** Return object used to calculate base Length
+ * for percent specifications.
+ */
+ public PercentBase getPercentBase(final FObj fo, final PropertyList propertyList) {
+ <xsl:choose>
+ <xsl:when test="@base">
+ return new LengthBase(fo, propertyList, LengthBase.<xsl:value-of select="@base"/>);
+ </xsl:when>
+ <xsl:otherwise>
+ return (new LengthBase(fo, propertyList, LengthBase.CUSTOM_BASE ) {
+ public int getBaseLength() {
+ return (<xsl:value-of select="."/>);
+ }
+ });
+ </xsl:otherwise>
+ </xsl:choose>
+ }
+</xsl:template>
+
+<!-- Look for "auto" length keyword -->
+<xsl:template match="auto-ok">
+ protected boolean isAutoLengthAllowed() {
+ return true;
+ }
+</xsl:template>
+
+<!-- Look for keyword equivalents. Value is the new expression -->
+<xsl:template match="keyword-equiv[1]">
+ protected String checkValueKeywords(String value) {
+ <xsl:for-each select="../keyword-equiv">
+ if (value.equals("<xsl:value-of select="@match"/>")) {
+ return new String("<xsl:value-of select="."/>");
+ }
+ </xsl:for-each>
+ return super.checkValueKeywords(value);
+ }
+</xsl:template>
+
+<xsl:template match="keyword-equiv[position()>1]"/>
+
+<!-- Generate code to convert from other datatypes to property datatype -->
+<xsl:template match='datatype-conversion[1]'>
+ <xsl:variable name="propclass">
+ <xsl:choose>
+ <xsl:when test="../compound">
+ <xsl:call-template name="propclass">
+ <xsl:with-param name="prop"
+ select="../compound/subproperty[@set-by-shorthand]"/>
+ </xsl:call-template>
+ </xsl:when><xsl:otherwise>
+ <xsl:call-template name="propclass">
+ <xsl:with-param name="prop" select=".."/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ // See if other value types are acceptable
+ protected Property convertPropertyDatatype(Property p,
+ PropertyList propertyList, FObj fo) {
+ <xsl:for-each select="../datatype-conversion">
+ {
+ <xsl:variable name="dtc">
+ <xsl:choose>
+ <xsl:when test="@vartype">
+ <xsl:value-of select="@vartype"/>
+ </xsl:when><xsl:otherwise>
+ <xsl:value-of select="@from-type"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:value-of select="$dtc"/><xsl:text> </xsl:text> <xsl:value-of select="@varname"/> =
+ p.get<xsl:value-of select="@from-type"/>();
+ if (<xsl:value-of select="@varname"/> != null) {
+ return new <xsl:value-of select="$propclass"/>(
+ <xsl:value-of select='.'/>);
+ }
+ }
+ </xsl:for-each>
+ return super.convertPropertyDatatype(p, propertyList, fo);
+ }
+</xsl:template>
+
+<xsl:template match="datatype-conversion[position()>1]"/>
+
+<!-- generate getDefaultForXXX for property components -->
+<xsl:template match="default[@subproperty]" priority="2">
+ <xsl:variable name="spname">
+ <xsl:call-template name="makeClassName">
+ <xsl:with-param name="propstr" select="@subproperty"/>
+ </xsl:call-template>
+ </xsl:variable>
+ protected String getDefaultFor<xsl:value-of select='$spname'/>() {
+ return "<xsl:value-of select='.'/>";
+ }
+</xsl:template>
+
+<!-- generate default "make" method for non-compound properties -->
+<xsl:template match="default[not(../compound)]" priority="1">
+ <xsl:if test='not(@contextdep = "true")'>
+ private Property m_defaultProp=null;
+ </xsl:if>
+ public Property make(PropertyList propertyList) throws FOPException {
+ <xsl:choose><xsl:when test='@contextdep="true"'>
+ return make(propertyList, "<xsl:value-of select='.'/>", propertyList.getParentFObj());
+ </xsl:when><xsl:otherwise>
+ if (m_defaultProp == null) {
+ m_defaultProp=make(propertyList, "<xsl:value-of select='.'/>", propertyList.getParentFObj());
+ }
+ return m_defaultProp;
+ </xsl:otherwise></xsl:choose>
+ }
+</xsl:template>
+
+<xsl:template match="text()"/>
+
<!-- Ignore properties which reference others. Only for mapping! -->
<xsl:template match="property[@type='ref']"/>
<!-- Look for compound properties -->
<xsl:if test="compound">
<xsl:for-each select="compound/subproperty">
- final private static Property.Maker s_<xsl:value-of select="name"/>Maker =
+ <xsl:variable name="spname">
+ <xsl:call-template name="makeClassName">
+ <xsl:with-param name="propstr" select="name"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test='*[local-name(.)!="name" and local-name(.)!="datatype"]'>
+ static private class SP_<xsl:value-of select="$spname"/>Maker
+ extends <xsl:value-of select="datatype"/>Property.Maker {
+ SP_<xsl:value-of select="$spname"/>Maker(String sPropName) {
+ super(sPropName);
+ }
+ <xsl:apply-templates select="percent-ok|auto-ok|keyword-equiv|datatype-conversion"/>
+ }
+ final private static Property.Maker s_<xsl:value-of select="$spname"/>Maker =
+ new SP_<xsl:value-of select="$spname"/>Maker(
+ "<xsl:value-of select='../../name'/>.<xsl:value-of select='name'/>");
+ </xsl:when>
+ <xsl:otherwise>
+ final private static Property.Maker s_<xsl:value-of select="$spname"/>Maker =
new <xsl:value-of select="datatype"/>Property.Maker(
"<xsl:value-of select='../../name'/>.<xsl:value-of select='name'/>");
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:for-each>
</xsl:if>
<xsl:if test="compound">
protected Property.Maker getSubpropMaker(String subprop) {
<xsl:for-each select="compound/subproperty">
+ <xsl:variable name="spname">
+ <xsl:call-template name="makeClassName">
+ <xsl:with-param name="propstr" select="name"/>
+ </xsl:call-template>
+ </xsl:variable>
if (subprop.equals("<xsl:value-of select='name'/>"))
- return s_<xsl:value-of select="name"/>Maker;
+ return s_<xsl:value-of select="$spname"/>Maker;
</xsl:for-each>
return super.getSubpropMaker(subprop);
}
<xsl:value-of select="datatype"/> val =
((<xsl:value-of select="$propclass"/>)baseProp).get<xsl:value-of select="datatype"/>();
<xsl:for-each select="compound/subproperty">
- <xsl:variable name="capname">
- <xsl:call-template name="capfirst">
- <xsl:with-param name="str" select="name"/>
+ <xsl:variable name="spname">
+ <xsl:call-template name="makeClassName">
+ <xsl:with-param name="propstr" select="name"/>
</xsl:call-template>
</xsl:variable>
if (subpropName.equals("<xsl:value-of select='name'/>"))
- val.set<xsl:value-of select='$capname'/>(subProp.get<xsl:value-of select='datatype'/>());
+ val.set<xsl:value-of select='$spname'/>(subProp.get<xsl:value-of select='datatype'/>(), false);
else
</xsl:for-each>
return super.setSubprop(baseProp, subpropName, subProp);
<xsl:value-of select="datatype"/> val =
((<xsl:value-of select="$propclass"/>)baseProp).get<xsl:value-of select="datatype"/>();
<xsl:for-each select="compound/subproperty">
- <xsl:variable name="capname">
- <xsl:call-template name="capfirst">
- <xsl:with-param name="str" select="name"/>
+ <xsl:variable name="spname">
+ <xsl:call-template name="makeClassName">
+ <xsl:with-param name="propstr" select="name"/>
</xsl:call-template>
</xsl:variable>
if (subpropName.equals("<xsl:value-of select='name'/>"))
return new <xsl:value-of select='datatype'/>Property(
- val.get<xsl:value-of select='$capname'/>());
+ val.get<xsl:value-of select='$spname'/>());
</xsl:for-each>
return super.getSubpropValue(baseProp, subpropName);
}
-</xsl:if>
-
-<xsl:if test='not(default/@contextdep = "true")'>
+<xsl:choose>
+<!-- some subproperty default is context dependent; don't cache default! -->
+<xsl:when test='.//default[@contextdep="true"]'>
+ public Property make(PropertyList propertyList) throws FOPException {
+ return makeCompound(propertyList, propertyList.getParentFObj());
+ }
+</xsl:when>
+<xsl:otherwise>
private Property m_defaultProp=null;
-</xsl:if>
+ public Property make(PropertyList propertyList) throws FOPException {
+ if (m_defaultProp == null) {
+ m_defaultProp=makeCompound(propertyList, propertyList.getParentFObj());
+ }
+ return m_defaultProp;
+ }
+</xsl:otherwise>
+</xsl:choose>
+
+ protected Property makeCompound(PropertyList pList, FObj fo) throws FOPException {
+ <xsl:value-of select="datatype"/> p = new <xsl:value-of select="datatype"/>();
+ Property subProp;
+ <xsl:for-each select="compound/subproperty/name">
+ <xsl:variable name="spname">
+ <xsl:call-template name="makeClassName">
+ <xsl:with-param name="propstr" select="."/>
+ </xsl:call-template>
+ </xsl:variable>
+ // set default for subprop <xsl:value-of select="."/>
+ subProp = getSubpropMaker("<xsl:value-of select='.'/>").make(pList,
+ getDefaultFor<xsl:value-of select='$spname'/>(), fo);
+ p.set<xsl:value-of select='$spname'/>(subProp.get<xsl:value-of select='../datatype'/>(), true);
+ </xsl:for-each>
+ return new <xsl:value-of select="$propclass"/>(p);
+ }
+
+ <!-- generate a "getDefaultForXXX" for each subproperty XXX -->
+ <xsl:for-each select="compound/subproperty">
+ <xsl:variable name="spname">
+ <xsl:call-template name="makeClassName">
+ <xsl:with-param name="propstr" select="name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ protected String getDefaultFor<xsl:value-of select='$spname'/>() {
+ <xsl:choose><xsl:when test="default">
+ return "<xsl:value-of select='default'/>";
+ </xsl:when><xsl:otherwise>
+ return "";
+ </xsl:otherwise>
+ </xsl:choose>
+ }
+ </xsl:for-each>
+
+ /** Set the appropriate components when the "base" property is set. */
+ protected Property convertProperty(Property p, PropertyList pList,FObj fo)
+ throws FOPException
+ {
+<xsl:variable name="spdt">
+ <xsl:call-template name="check-subprop-datatype">
+ <xsl:with-param name="dtlist"
+ select="compound/subproperty[@set-by-shorthand='true']/datatype"/>
+ </xsl:call-template>
+</xsl:variable>
+<!--
+ Property sub= getSubpropMaker("<xsl:value-of select='compound/subproperty[@set-by-shorthand="true"]/name'/>").convertProperty(p,pList,fo);
+ if (sub != null) {
+ <xsl:value-of select='$spdt'/> spval=sub.get<xsl:value-of select='$spdt'/>();
+-->
+ <xsl:value-of select='$spdt'/> spval=p.get<xsl:value-of select='$spdt'/>();
+ if (spval == null) {
+ // NOTE: must convert to the component datatype, not compound!
+ Property pconv = convertPropertyDatatype(p, pList, fo);
+ if (pconv != null) {
+ spval=pconv.get<xsl:value-of select='$spdt'/>();
+ }
+ }
+ if (spval != null) {
+ Property prop = makeCompound(pList, fo);
+ <xsl:value-of select='datatype'/> pval = prop.get<xsl:value-of select='datatype'/>();
+<xsl:for-each select="compound/subproperty[@set-by-shorthand='true']">
+ <xsl:variable name="spname"><xsl:call-template name="makeClassName">
+ <xsl:with-param name="propstr" select="name"/>
+ </xsl:call-template></xsl:variable>
+ pval.set<xsl:value-of select='$spname'/>(spval, false);
+</xsl:for-each>
+ return prop;
+ }
+ else {
+ // throw some kind of exception!
+ throw new FOPException("Can't convert value to <xsl:value-of select='$spdt'/> type");
+ }
+ }
+
+</xsl:if> <!-- property/compound -->
<xsl:if test="inherited">
public boolean isInherited() { return <xsl:value-of select="inherited"/>; }
}
</xsl:if>
-<!-- Content of element is code to calculate the base length -->
-<xsl:if test="percent-ok">
- static class PropLengthBase extends LengthBase {
- private FObj fo;
- private PropertyList propertyList ;
-
- public PropLengthBase(FObj fo, PropertyList plist) {
- this.fo = fo;
- // get from FO????
- this.propertyList = plist;
- //this.propertyList = fo.getProperties();
- }
-
- public int getBaseLength() {
-<xsl:choose>
- <xsl:when test="percent-ok/@base='FONTSIZE'">
- return propertyList.get("font-size").getLength().mvalue();
- </xsl:when>
- <xsl:when test="percent-ok/@base='INH-FONTSIZE'">
- return propertyList.getInherited("font-size").getLength().mvalue();
- </xsl:when>
- <xsl:when test="percent-ok/@base='CONTAINING-BOX'">
- <!-- should probably distinguish width and height... -->
- return fo.getContainingWidth();
- </xsl:when>
- <xsl:otherwise>
- return <xsl:value-of select="percent-ok"/>;
- </xsl:otherwise>
-</xsl:choose>
- }
- }
-
- /** Return instance of internal class to calculate base Length
- * for percent specifications.
- */
- public PercentBase getPercentBase(final FObj fo,
- final PropertyList propertyList) {
- return new PropLengthBase(fo, propertyList);
- }
-</xsl:if>
-
-<!-- Look for "auto" length keyword -->
-<xsl:if test="auto-ok">
- protected boolean isAutoLengthAllowed() {
- return true;
- }
-</xsl:if>
-
-
<!-- Handle enumerated values -->
<xsl:if test="enumeration/value">
protected Property findConstant(String value) {
}
</xsl:if>
-<!-- Look for keyword equivalents. Value is the new expression -->
-<xsl:if test="keyword-equiv">
- protected String checkValueKeywords(String value) {
- <xsl:for-each select="keyword-equiv">
- if (value.equals("<xsl:value-of select="@match"/>")) {
- return new String("<xsl:value-of select="."/>");
- }
- </xsl:for-each>
- return super.checkValueKeywords(value);
- }
-</xsl:if>
-
-<!-- Generate code to convert from other datatypes to property datatype -->
-<xsl:if test='datatype-conversion'>
- // See if other value types are acceptable
- protected Property convertPropertyDatatype(Property p,
- PropertyList propertyList, FObj fo) {
- <xsl:for-each select="datatype-conversion">
- {
- <xsl:variable name="dtc">
- <xsl:choose>
- <xsl:when test="@vartype">
- <xsl:value-of select="@vartype"/>
- </xsl:when><xsl:otherwise>
- <xsl:value-of select="@type"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:value-of select="$dtc"/><xsl:text> </xsl:text> <xsl:value-of select="@varname"/> =
- p.get<xsl:value-of select="@type"/>();
- if (<xsl:value-of select="@varname"/> != null) {
- return new <xsl:value-of select="$propclass"/>(
- <xsl:value-of select='.'/>);
- }
- }
- </xsl:for-each>
- return super.convertPropertyDatatype(p, propertyList, fo);
- }
-</xsl:if>
-
-<xsl:if test="default">
- public Property make(PropertyList propertyList, boolean bForceNew) throws FOPException {
- <xsl:choose><xsl:when test='default/@contextdep="true"'>
- return make(propertyList, "<xsl:value-of select="default"/>", null);
- </xsl:when><xsl:otherwise>
- if (bForceNew) {
- // Make a new property instead of using the static default
- return make(propertyList, "<xsl:value-of select="default"/>", null);
- }
- if (m_defaultProp == null)
- m_defaultProp=make(propertyList, "<xsl:value-of select="default"/>", null);
- return m_defaultProp;
- </xsl:otherwise></xsl:choose>
- }
-</xsl:if>
-
<!-- Currently only works for Enum values -->
<xsl:if test="derive">
public Property compute(PropertyList propertyList) {
return computedProperty;
}
</xsl:if>
+<xsl:apply-templates select="percent-ok|auto-ok|default|keyword-equiv|datatype-conversion"/>
}
</redirect:write>
</xsl:if> <!-- need to create a class -->
<!-- avoid unwanted output to placeholder file -->
<xsl:template match="localname"/>
-</xsl:stylesheet>
-
+<!-- Check that each member of the nodeset dtlist has the same value.
+ Print a message if any member of dtlist is different
+ from the first member. Return the first member.
+ -->
+<xsl:template name="check-subprop-datatype">
+ <xsl:param name="dtlist"/>
+ <xsl:variable name="dt"><xsl:value-of select='$dtlist[1]'/></xsl:variable>
+ <xsl:for-each select="$dtlist">
+ <xsl:if test=". != $dt">
+ <xsl:message>
+ <xsl:text>Conflict between subproperty datatypes: </xsl:text>
+ <xsl:value-of select='.'/> != <xsl:value-of select='$dt'/>
+ </xsl:message>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:value-of select='$dt'/>
+</xsl:template>
+</xsl:stylesheet>