我有一个XML定义,其中包含一个包含子元素的元素。例如:
<a>
<b>
<c>C</c>
<d>D</d>
</b>
</a>
我有一个带有文本输出的XSLT。例如:
<xsl...>
<xsl:output method="text" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select="/a/b" />
...
我想将整个b元素及其子元素复制到空格删除的字符串中,以便生成SQL查询。例如:
select * from some-table where xml = '<b><c>C</c><d>D</d></b>'
目前copy-of正在寻找b元素,但是删除了所有元素和属性信息,只留下每个元素和属性信息。我认为这可能与输出类型有关。
有什么想法吗?
答案 0 :(得分:1)
你的SQL语句吓到我了。 XML区分大小写,如果输入XML和XSLT(包括所有元素,属性和值)的设置与原始数据库插入中使用的完全不同,那么您的比较可能会失败。
我相信Oracle(某些)和SQL Server(如此)都有机制以更加XML友好的方式对包含XML的列进行查询(例如,使用XPath)。
你到底想要做什么?您的问题似乎比让XSLT正确转换更深刻。
答案 1 :(得分:1)
对于XSLT来说,可能有点挑战性的任务。我能得到的最接近的是:
<xsl:template match="b//*|node()">
<xsl:copy>
<xsl:text><</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>></xsl:text>
<xsl:value-of select="text()"/>
<xsl:apply-templates select="*"/>
<xsl:text></</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>></xsl:text>
</xsl:copy>
</xsl:template>
并且被称为:
<xsl:apply-templates select="/a/b/self::*"/>
这会产生以下结果:
<b>
<c>C</c>
<d>D</d>
</b>
我的“解决方案”落在哪里是元素具有属性的时候。如果b具有属性,则会写出属性值。我找不到一种方法来写出属性,当它们出现时;重新遇到......
有什么想法吗?
答案 2 :(得分:-1)
以下是如何做到的:
<xsl:output method="xml" />
<xsl:template match="/"><xsl:apply-templates select="/a/b" mode="normalize-space" /></xsl:template>
<xsl:template match="text()" mode="normalize-space"><xsl:value-of select="normalize-space(.)" /></xsl:template>
<xsl:template match="@*|node()" mode="normalize-space"><xsl:copy><xsl:apply-templates select="@*|node()" mode="normalize-space" /></xsl:copy></xsl:template>
此方法复制节点,具有名称空间和属性的节点。
方法要求输出为“xml”(不是原始样本中的“text”)。它为所有TEXT节点使用自定义模板来规范化其中的空间(删除前导/尾随空格,将多个空格压缩到单个空间中)。然后,它使用简单的“身份”模板来复制所有节点及其属性。两个模板都使用特殊模式,不会干扰XSL的其余部分。
不幸的是,XSLT处理器将xsl:template标记内的所有“未知”节点复制到输出文档中,空格就是这样的节点之一。这就是为什么所有这些模板都需要写成一行而没有多余空格的原因。
PS虽然,我同意在RDBMS中搜索规范化的XML有点奇怪。