将相同的标记、不同的命名空间视为相同
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:h1
和 ns2: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。在这个简单的步骤之后,所有文档都将位于同一命名空间中,因此您可以对两者使用完全相同的转换逻辑。与尝试在每个处理点处理两个命名空间相比,这种方法对您的转换逻辑的破坏要小得多。
我正在做一个项目,我有 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:h1
和 ns2: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。在这个简单的步骤之后,所有文档都将位于同一命名空间中,因此您可以对两者使用完全相同的转换逻辑。与尝试在每个处理点处理两个命名空间相比,这种方法对您的转换逻辑的破坏要小得多。