将相同的标记,不同的名称空间视为相同

时间:2015-02-12 18:57:36

标签: xml xslt xslt-1.0 xml-namespaces

我正在开发一个项目,我的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的

3 个答案:

答案 0 :(得分:3)

对于这样的简单匹配模式,最清晰的方法可能是在样式表中声明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">

答案 1 :(得分:2)

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

答案 2 :(得分:0)

不使用 XPath tagname,而是可以使用:

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

因此,如果*(名称不包含命名空间)等于local-name(),则匹配所有标记h1,然后按约束查找。因此,ns1:h1ns2:h1都匹配。

但是如果可能的话,最好使用h1而不是*[local-name()='h1']:某些引擎可能无法优化*[local-name()='h1'],从而开始枚举所有节点,而且它的可读性和难度更低保持。只给出建议......