XML XSL命名空间

时间:2011-12-05 20:44:18

标签: xml xslt xpath

我正在使用XSL从自动生成的XML文件创建报告。在文件中,我的根节点包含时间戳作为命名空间。当我生成带有XML文件中包含时间戳的HTML报告时,我无法在节点中提取该属性。当我删除它,它工作正常。有人可以对这个话题有所了解。感谢。

时间戳:

<AdminReports xmlns="30/11/2011 09:25:58">

<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE AdminReports []>
<?xml-stylesheet type="text/xsl" href="AdminReport.xsl"?>

<AdminReports xmlns="30/11/2011 09:25:58">
  <AdminReport ID="1">
  </AdminReport >
</AdminReports>

3 个答案:

答案 0 :(得分:0)

此值不应存储在xmlns中,但您可以使用namespace-uri()在XPath 2.0中访问它:

 namespace-uri(/*:AdminReports)

答案 1 :(得分:0)

xmlns="..."不是属性声明,而是名称空间声明。这意味着元素AdminReports位于命名空间中。

我认为在你的XSL中,没有与以下URI“30/11/2011 09:25:58”对应的名称空间声明。因此,XSL不会给你预期的结果。如果在删除命名空间声明后获得了良好的结果,那么这意味着您的XSL适用于没有命名空间的XML。

在转换之前,您可以添加第一个XSL来删除命名空间。例如:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:for-each select="@*">
                <xsl:attribute name="{local-name()}" >
                    <xsl:value-of select="."/>
                </xsl:attribute>
            </xsl:for-each>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>    
</xsl:stylesheet>

另一种选择可能是更改您的XSL,使其成为“名称空间感知”。

答案 2 :(得分:0)

因为默认命名空间的namespace-uri是时间戳 - 这意味着它对于每个自动生成的文档可能不同,所以无法在XSLT代码中定义“this”命名空间

存在另一种方式 - 不直接使用未加前缀的名称,而是将它们与元素的name()进行比较:

/*/*[name()='AdminReport']/@ID

正确选择名为“AdminReport”的任何元素的ID属性(关于它所属的命名空间),它是XML文档顶部元素的子元素。

这是一个完整的XSLT示例

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:value-of select=
    "/*/*[name()='AdminReport']/@ID"/>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML文档

<AdminReports xmlns="30/11/2011 09:25:58">
    <AdminReport ID="1">
    </AdminReport >
</AdminReports>

产生了需要的正确结果

1