如何在XSLT 1.0中匹配和处理未知的XML元素?

发布于 2024-11-05 17:43:50 字数 621 浏览 3 评论 0原文

我有一个简单的 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 复杂得多,我就不喜欢。

I have a simply XSLT 1.0 stylesheet, that turns XML documents in XHTML. I really want to be able to "include" the content of an XML file in another when needed. AFAIK it is simply not possible in XSLT 1.0, so I decided to move my processing to a simple Java app that would pre-process the XML, executing the "includes" recursively, and passing it to the default JDK XSLT processor. I have a XML schema that my documents must conform to.

The most used element is called "text", and can have an "id" and/or a "class" attribute, which gets used for XHTML styling with CSS. This element gets turned into "p", "div", or "span" depending on the context.

What I would like to add, is the ability to define "unknown" elements in my input files, and have them transformed in a "text" element for further processing. If the "unknown" element's name start with a capital letter, then it becomes a "text", with "id" set to original name. Otherwise a "text" with "class" set to original name. Everything else in the unknown element should be kept as-is, and then it should be processed by XSLT as if it was originally in the input file. In other words, I would like to transform all unknown elements to for a valid XML document, and then process it with my stylesheet.

Can this be done in XSLT, possibly in a pre-processing "stylesheet", or should I do that as pre-processing in Java? Performance here is not important. I would prefer a XSLT solution, but not if it's much more complicated then doing it in Java.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

非要怀念 2024-11-12 17:43:50

好吧,既然没有人回答,我就试了一下。虽然在 Java 中更容易做到这一点,但它有一个主要缺点:由于代码需要知道有效元素以便识别未知元素,因此您最终必须在代码中对其进行硬编码,并且如果出现以下情况则必须重新编译它: XSLT 模板更改。

所以,我尝试了 XSLT,它也有效。假设您有:

<xsl:template match="text">
    *processing*
    <xsl:call-template name="id_and_class"/>
    *processing*
</xsl:template>

名为 id_and_class 的模板复制生成元素中的 id 和 classes 属性,并且您希望将未知元素映射到“文本”元素,那么您可以执行以下操作:

<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>

如果您使用命名模板处理一个特定元素的内容,那么您可以签入该模板(如果名称匹配),并将其用于您的特殊处理。然后你只需要放置一个在样式表的末尾并从那里调用命名模板。

Well, since no one answered, I just tried it. While is is easier to do it in Java, it has one major drawback: since the code need to know the valid elements so that it recognize the unknown ones, you end up having to hardcode that in your code and have to recompile it if the XSLT template changes.

So, I tried in XSLT and it also works. Let's say you have:

<xsl:template match="text">
    *processing*
    <xsl:call-template name="id_and_class"/>
    *processing*
</xsl:template>

where the template named id_and_class copies your id and classes attribute in the generated element, and you want unknown elements to be mapped to "text" elements, then you can do this:

<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>

If yon process the content of one specific element with a named template, then you can check in that template if the name matches, and use that for your special processing. Then you just have to put a <xsl:template match="*"> at the end of your stylesheet and call the named template from there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文