我有一个简单的XSLT 1.0样式表,它将XML文档转换为XHTML。我真的希望能够在需要时将XML文件的内容"包含"到另一个文件中。AFAIK 这在 XSLT 1.0 中根本不可能,所以我决定将我的处理转移到一个简单的 Java 应用程序,该应用程序将预处理 XML,以递归方式执行"包含",并将其传递给默认的 JDK XSLT 处理器。我有一个我的文档必须符合的 XML 架构。
最常用的元素称为"text",可以具有"id"和/或"class"属性,用于CSS的XHTML样式。此元素会根据上下文转换为"p"、"div"或"span"。
我想补充的是,能够在我的输入文件中定义"未知"元素,并将它们转换为"文本"元素以进行进一步处理。如果"未知"元素的名称以大写字母开头,则它将成为"文本",并将"id"设置为原始名称。否则,将"类"设置为原始名称的"文本"。未知元素中的其他所有内容都应保持原样,然后由 XSLT 处理它,就像它最初在输入文件中一样。换句话说,我想将所有未知元素转换为有效的XML文档,然后使用我的样式表对其进行处理。
这可以在 XSLT 中完成,可能在预处理"样式表"中完成,还是应该在 Java 中作为预处理来完成?这里的性能并不重要。我更喜欢 XSLT 解决方案,但如果它比在 Java 中做要复杂得多,则不会。
好吧,既然没有人回答,我就试了一下。虽然在 Java 中更容易做到这一点,但它有一个主要缺点:由于代码需要知道有效元素才能识别未知元素,因此您最终必须在代码中对其进行硬编码,并且必须在 XSLT 模板更改时重新编译它。
所以,我尝试了XSLT,它也可以工作。假设您有:
<xsl:template match="text">
*processing*
<xsl:call-template name="id_and_class"/>
*processing*
</xsl:template>
如果名为 id_and_class 的模板在生成的元素中复制您的 id 和 classes 属性,并且您希望将未知元素映射到"text"元素,那么您可以这样做:
<xsl:template match="text">
<xsl:call-template name="text_processing"/>
</xsl:template>
<xsl:template name="text_processing">
*processing*
<xsl:call-template name="text_id_and_class"/>
*processing*
</xsl:template>
...
<xsl:template name="text_id_and_class">
<xsl:choose>
<!-- If name() is not "text", then we have an unknown element. -->
<xsl:when test="name()!='text'">
<!-- Processing of ID and class omitted ... -->
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="id_and_class"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
...
<!-- MUST BE LAST : Process unknown elements like a "text" element. -->
<xsl:template match="*">
<xsl:call-template name="text_processing"/>
</xsl:template>
如果使用命名模板处理一个特定元素的内容,则可以签入该模板(如果名称匹配),并将其用于特殊处理。然后,您只需要在样式表的末尾放置一个<xsl:template>,并从那里调用命名模板。