【发布时间】:2022-01-14 11:34:24
【问题描述】:
我们在内部使用XSLT 将单个输入模式映射到大量不同的输出模式。大多数使用这些模式的服务器在空元素上返回错误,因此空元素不能出现在输出中。在许多情况下,输入中的一条数据将简单地映射到输出中的一条数据,可能需要进行较小的转换,例如:
<!-- Input -->
<ourns:DateCreated>2021-12-09</ourns:DateCreated>
<!-- Output -->
<otherns:CreatedDt>2021-12-09<otherns:CreatedDt>
用于此的 XSLT 很简单,即使有“无空元素”要求:
<xsl:if test="ourns:DateCreated != ''">
<otherns:CreatedDt>
<xsl:value-of select="ourns:DateCreated/text()"/>
</otherns:CreatedDt>
</xsl:if>
但是,当您在数百个模式中映射数千个元素时,将所有内容包装在 <xsl:if/> 中的这种业务会变得很烦人。你可以添加一个函数,比如:
<xsl:function name="ourfn:createElementIfData">
<xsl:param name="tag" as="xs:string"/>
<xsl:param name="data" as="xs:string"/>
<xsl:if test="$data != ''">
<xsl:element name="{$tag}"><xsl:value-of select="$data"/></xsl:element>
</xsl:if>
</xsl:function>
...
<xsl:sequence select="ourfn:createElementIfData('otherns:CreatedDt', ourns:DateCreated)"/>
但是这个函数只有在声明了两个命名空间的样式表中才能工作。如果你想分享它(就像你可能会想要这样一个通用功能),你最终需要要么
- 在共享样式表中声明所有可能的
otherns,或 - 在每次调用时传入完全限定的命名空间,
两者都感觉不对。
这似乎是一个常见的用例,我觉得必须有一种简单的方法来做到这一点。我错过了什么?
【问题讨论】:
标签: xslt xml-namespaces xslt-3.0