Isa*_*aac 4 xml xslt namespaces
在搜索网络寻找答案后,提出"几乎"解决方案......我决定将问题简化为一个非常简单的案例.
请考虑以下XML代码段:
<me:root xmlns:me="http://stackoverflow.com/xml"
xmlns="http://www.w3.org/1999/xhtml">
<me:element>
<p>Some HTML code here.</p>
</me:element>
</me:root>
Run Code Online (Sandbox Code Playgroud)
请注意,该p元素是XHTML的命名空间,这是此doc的默认命名空间.
现在考虑以下简单的样式表.我想创建一个XHTML文档,其内容me:element为body.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:me="http://stackoverflow.com/xml"
xmlns="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="me">
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My Title</title>
</head>
<body>
<xsl:copy-of select="me:root/me:element/node()"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
请注意,我包括exclude-result-prefixes......但看看我得到了什么:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My Title</title>
</head>
<body>
<p xmlns:me="http://stackoverflow.com/xml">Some HTML code here.</p>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
而这让我疯狂的是为什么,为什么会xmlns:me出现在p元素内?
无论我尝试什么,我都无法上班.我有一种奇怪的感觉,问题出在我的xsl:copy-of陈述上.
我有一种奇怪的感觉,问题出在我的
xsl:copy-of陈述上.
这正是原因所在.
源XML文档包含此片段:
<me:element>
<p>Some HTML code here.</p>
</me:element>
Run Code Online (Sandbox Code Playgroud)
在XPath数据模型中,命名空间节点从子树的根传播到其所有后代.因此,该<p>元素具有以下命名空间:
"http://www.w3.org/1999/xhtml"
"http://stackoverflow.com/xml"
"http://www.w3.org/XML/1998/namespace"
http://www.w3.org/2000/xmlns/
最后两个是保留名称空间(用于前缀xml:和xmlns),可用于任何命名节点.
报告的问题是由于根据定义,<xsl:copy-of>指令将所有节点及其完整子树复制到属于每个节点的所有名称空间.
请记住:指定为exclude-result-prefixes属性值的前缀仅从literal-result元素中排除!
方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:me="http://stackoverflow.com/xml"
xmlns="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="me">
<xsl:output method="xml" omit-xml-declaration="yes"
indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My Title</title>
</head>
<body>
<xsl:apply-templates select="me:root/me:element/*"/>
</body>
</html>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当此转换应用于提供的XML文档时:
<me:root xmlns:me="http://stackoverflow.com/xml"
xmlns="http://www.w3.org/1999/xhtml">
<me:element>
<p>Some HTML code here.</p>
</me:element>
</me:root>
Run Code Online (Sandbox Code Playgroud)
产生了想要的正确结果:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My Title</title>
</head>
<body>
<p>Some HTML code here.</p>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)