执行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()吗?也许是名称空间的问题?
谢谢。
答案 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>