将相同的标记、不同的命名空间视为相同

Treat same tag, different namespace as the same

我正在做一个项目,我有 xml 个文件,其中包含 html 个子节点;有些具有 xmlns="http://www.w3.org/1999/xhtml" 属性,有些则没有。 (在之前的过程中,脚本检查 html 部分的格式是否正确,并在需要时使用 htmltidy 清理它们)

有这样的 xml 文件吗:

<?xml version="1.0"?>
<root>
    <html>
        <h1>html with no namespace</h1>
        <p>regular html.</p>
    </html>
    <html xmlns="http://www.w3.org/1999/xhtml">
        <h1>xhtml with namespace declaration</h1>
        <p>this has a ns, so all tags under it share that ns.</p>
    </html>
</root>

和这样的样式表:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <newroot>
        <xsl:apply-templates/>
    </newroot>
</xsl:template>

<xsl:template match="h1">
    <newhead>
        <xsl:apply-templates/>
    </newhead>
</xsl:template>
<xsl:template match="p">
    <newpara>
        <xsl:apply-templates/>
    </newpara>
</xsl:template>


</xsl:stylesheet>

将两个 html 集合视为相同? 谢谢, bp

不使用 as XPath tagname,可以使用:

<xsl:template match="*[local-name()='h1']">

因此您匹配所有标签 *,然后根据约束条件查找 local-name()(名称不包括命名空间)是否等于 h1。结果 ns1:h1ns2:h1 都匹配。

然而,如果可能,最好使用 h1 而不是 *[local-name()='h1']:一些引擎可能无法优化 *[local-name()='h1'],因此开始枚举所有节点,而且它的可读性较差并且更难维护。只提供建议...

对于像这样的简单匹配模式,最清晰的方法可能是在样式表中声明 html 命名空间

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:h="http://www.w3.org/1999/xhtml"
                              exclude-result-prefixes="h">

然后在模板模式中列出两个备选方案

<xsl:template match="h1 | h:h1">

我的首选方法是预处理命名空间 A 中的文档以将它们放入命名空间 B。在这个简单的步骤之后,所有文档都将位于同一命名空间中,因此您可以对两者使用完全相同的转换逻辑。与尝试在每个处理点处理两个命名空间相比,这种方法对您的转换逻辑的破坏要小得多。