我有以下示例xml输入。
<RootElement xmlns="http://example.com">
<aa>test</aa>
<bb>ffff</bb>
<cc>dere</cc>
<givenDate>2016-07-23T00:00:00.000+00:00</givenDate>
</RootElement>我想生成以下响应消息。
{
"abc" : "2016-07-23"
}为此,我尝试使用以下xslt。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://example.com" version="1.0" exclude-result-prefixes="ns">
<xsl:output method="text" omit-xml-declaration="yes" indent="no" encoding="UTF-8" media-type="application/json"/>
<xsl:template match="/">
<xsl:text>{</xsl:text>
<xsl:text>"abc": </xsl:text>
<xsl:variable name="givenDate" select="substring-before(//ns:RootElement/ns:givenDate, 'T')"/>
<xsl:value-of select="ns:set_value($givenDate)"/>
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:function name="ns:set_value">
<xsl:param name="givenDate"/>
<xsl:choose>
<xsl:when test="$givenDate/text() !=''">
<xsl:text>"</xsl:text><xsl:value-of select="$givenDate"/><xsl:text>"</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>null</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>在那个时候,我得到了下面的错误信息。无法使用提供的XML/XSL输入生成XML文档。'/‘的第一个操作数的必需项类型是节点();所提供的值具有项目类型xs:string
我对XSLT不太熟悉。你对这件事有什么想法吗?
发布于 2019-05-06 17:42:35
经过几次尝试,我可以解决这个问题。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://example.com" version="1.0" exclude-result-prefixes="ns" xmlns:func="http://exslt.org/functions">
<xsl:output method="text" omit-xml-declaration="yes" indent="no" encoding="UTF-8" media-type="application/json"/>
<xsl:template match="/">
<xsl:text>{</xsl:text>
<xsl:text>"abc": </xsl:text>
<xsl:variable name="givenDate" select="substring-before(//ns:RootElement/ns:givenDate, 'T')"/>
<xsl:value-of select="ns:set_value($givenDate)"/>
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:function name="ns:set_value">
<xsl:param name="givenDate"/>
<xsl:choose>
<xsl:when test="$givenDate !=''">
<func:result>
<xsl:text>"</xsl:text>
<xsl:value-of select="$givenDate"/>
<xsl:text>"</xsl:text>
</func:result>
</xsl:when>
<xsl:otherwise>
<xsl:text>null</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>发布于 2019-05-06 15:31:08
无法使用提供的XML/XSL输入生成XML文档。'/‘的第一个操作数的必需项类型是节点();所提供的值具有项目类型xs:string ..。你对这件事有什么想法吗?
该消息意味着步骤路径运算符/ 的左手参数必须是节点类型的。因为您已经将$givenDate声明为substring-before(...),所以它将是xs:string类型。因此,在表达式$givenDate/text()中使用它时出现的错误,正如zx485 comment已经指出的那样
我认为最好在函数本身中执行从xs:dateTime到xs:date或'null'的转换,比如在XSLT2.0样式表中:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://example.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="ns xs">
<xsl:output method="text" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:text>{
"abc": </xsl:text>
<xsl:value-of select="ns:set_value(//ns:RootElement/ns:givenDate)"/>
<xsl:text>
}</xsl:text>
</xsl:template>
<xsl:function name="ns:set_value">
<xsl:param name="givenDate"/>
<xsl:sequence
select="if ($givenDate castable as xs:dateTime)
then xs:date(xs:dateTime($givenDate))
else 'null'"/>
</xsl:function>
</xsl:stylesheet>输出:
{
"abc": 2016-07-23Z
}注意:如果您有dateTime数据,则强制转换将保留时区信息。
发布于 2019-05-06 19:43:03
我认为您已经发现了错误,但是错误(或解决错误的困难)的根本原因是没有声明变量和参数的类型。如果您遵循函数的参数和结果应该始终具有声明类型的规则,那么您可能会问自己该函数接受什么样的值以及它返回什么,并且您可能已经确定输入和输出都是字符串,从而导致声明:
<xsl:function name="ns:set_value" as="xs:string">
<xsl:param name="givenDate" as="xs:string"/>有了这些声明,编译器就可以直接告诉您出了什么问题。$givenDate/text()没有意义,因为字符串没有子文本节点;并且返回值
<xsl:text>"</xsl:text>
<xsl:value-of select="$givenDate"/>
<xsl:text>"</xsl:text>没有意义,因为文本节点序列不能转换为字符串。返回字符串结果的最简单和最直接的方法可能是
<xsl:sequence select='concat("""", $givenDate, """")'/> 不过,如果您想避免乱搞转义引号,那么另一种选择将是鲜见的。
<xsl:value-of>
<xsl:text>"</xsl:text>
<xsl:value-of select="$givenDate"/>
<xsl:text>"</xsl:text>
</xsl:value-of>它将三个文本节点组合为一个(类型声明as="xs: string“,然后将文本节点隐式转换为字符串。你也可以把这个缩写为
<xsl:value-of>"<xsl:value-of select="$givenDate"/>"</xsl:value-of>或者在XSLT3.0中,使用expand-text="yes"可以使用文本值模板:
<xsl:value-of>"{$givenDate}"</xsl:value-of> https://stackoverflow.com/questions/56006489
复制相似问题