XSL转换返回空白值

时间:2018-10-12 07:48:50

标签: xslt xslt-2.0

执行xsl转换时,我在检索输入数据时遇到问题。

这是我原始的xml输入(输入xml)

<?xml version="1.0" encoding="UTF-8"?> <ns2:pointOfSale 
xmlns:ns2="http://example.net/.." 
mode="CREATE" timestamp="2018-10-12T09:34:53.14+02:00"><ns2:id 
type="AMP">15573</ns2:id></ns2:pointOfSale>

这是我的输出结果(输出xml)

<?xml version="1.0" encoding="utf-8"?><clients xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="setClients.xsd" encryptedData="N"><client clientID=""></client></clients>

这是我的xsl

<?xml version="1.1" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns2="http://example.net/.."
exclude-result-prefixes="xs xd"
version="2.0">

<xsl:output method="xml" version="1.0" encoding="utf-8" omit-xml-declaration="no" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
    <xsl:element name="clients">
        <xsl:attribute 
        name="xsi:noNamespaceSchemaLocation">setClients.xsd</xsl:attribute>
        <xsl:attribute name="encryptedData">N</xsl:attribute>
                <xsl:element name="client">
                    <xsl:attribute name="clientID" >
                    <xsl:value-of select="ns2:id"/>
                    </xsl:attribute>
                </xsl:element>
    </xsl:element>
</xsl:template>
</xsl:stylesheet>

就像您看到的那样,元素ID的值为空(“”)

出什么问题了?是match()吗?也许是名称空间的问题?

谢谢。

1 个答案:

答案 0 :(得分:2)

<xsl:value-of select="id"/>不返回任何内容的原因有两个。

首先,您的模板匹配"/",即文档节点。这是XML中ns2:pointOfSale节点的父级。文档节点没有id作为子节点,因此<xsl:value-of select="id"/>将找不到任何内容。要解决此问题,您应该匹配根元素(在本例中为ns2:pointOfSale

<xsl:template match="/*">

第二个问题是名称空间。假设XML中存在xmlns:ns2="xxx.xxxx"形式的名称空间声明,则可以在XSLT中(xsl:stylesheet元素上)添加相同的声明,然后就可以这样做。

<xsl:value-of select="ns2:id"/>

在XSLT中没有对命名空间的任何引用,它将在没有命名空间的情况下寻找id元素。

尝试此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xs xd"
xmlns:ns2="xxx.xxxx"
version="2.0">

<xsl:output method="xml" version="1.0" encoding="utf-8" omit-xml-declaration="no" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
    <xsl:element name="clients">
        <xsl:attribute 
        name="xsi:noNamespaceSchemaLocation">setClients.xsd</xsl:attribute>
        <xsl:attribute name="encryptedData">N</xsl:attribute>
                <xsl:element name="client">
                    <xsl:attribute name="clientID" >
                    <xsl:value-of select="ns2:id"/>
                    </xsl:attribute>
                </xsl:element>
    </xsl:element>
</xsl:template>
</xsl:stylesheet>

实际上,当您使用XSLT 2.0时,可以改用xpath-default-namespace,这意味着XSLT会将select表达式中任何未前缀的元素都视为该命名空间的一部分。

也尝试一下。...

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xs xd"
xpath-default-namespace="xxx.xxxx"
version="2.0">

<xsl:output method="xml" version="1.0" encoding="utf-8" omit-xml-declaration="no" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
    <xsl:element name="clients">
        <xsl:attribute 
        name="xsi:noNamespaceSchemaLocation">setClients.xsd</xsl:attribute>
        <xsl:attribute name="encryptedData">N</xsl:attribute>
                <xsl:element name="client">
                    <xsl:attribute name="clientID" >
                    <xsl:value-of select="id"/>
                    </xsl:attribute>
                </xsl:element>
    </xsl:element>
</xsl:template>
</xsl:stylesheet>

更好的是,使用属性值模板(并避免使用xsl:element)将XSLT简化为此...

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xs xd"
xpath-default-namespace="xxx.xxxx"
version="2.0">

<xsl:output method="xml" version="1.0" encoding="utf-8" omit-xml-declaration="no" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
    <clients xsi:noNamespaceSchemaLocation="setClients.xsd" encryptedData="N">
        <client clientID="{id}" />
    </clients>
</xsl:template>
</xsl:stylesheet>