简体   繁体   中英

XML XSL Namespace

I am creating a report from an auto-generated XML file using XSL. In the file my root node contains the time stamp as a namespace. When I generate my HTML report with time stamp included in the XML file, I am not able to pull the attribute in the node. When I delete it, it works fine. Can someone shed a little light on this topic. Thanks.

with the timestamp:

<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>

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

 namespace-uri(/*:AdminReports)

xmlns="..." is not an attribute declaration but a namespace declaration. It means that the element AdminReports is in a namespace.

I presume that in your XSL, there's no namespace declaration corresponding to the following URI " 30/11/2011 09:25:58 ". Therefore, the XSL doen't give you the expected result. If you have the good result after deleting the namespace declaration, then it means that your XSL works for an XML without namespace.

Before transformation, you can add a first XSL to delete the namespaces. This one for example :

<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>

Another alternative could be to change your XSL so that it becomes "namespace aware".

Because the namespace-uri for the default namespace is a timestamp -- which means that it is potentially different for every auto-generated document, there is no way to define "this" namespace in the XSLT code .

There exists another way -- not using unprefixed names directly, but comparing them to the name() of the element:

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

correctly selects the ID attribute of any element named 'AdminReport' (regardles to which namespace it belongs), that is a child of the top element of the XML document.

Here is a complete XSLT example :

<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>

when this transformation is applied on the provided XML document :

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

the wanted, correst result is produced :

1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM