使用XML和XSLT生成SQL

使用XML和XSLT生成SQL,xml,xslt,Xml,Xslt,我有一个XML定义,它包含一个带有子元素的元素。例如: <a> <b> <c>C</c> <d>D</d> </b> </a> <xsl...> <xsl:output method="text" indent="yes"/> <xsl:template match="/"> <xsl:copy-of select="/a/b"

我有一个XML定义,它包含一个带有子元素的元素。例如:

<a>
 <b>
  <c>C</c>
  <d>D</d>
 </b>
</a>
<xsl...>
  <xsl:output method="text" indent="yes"/>
  <xsl:template match="/">
    <xsl:copy-of select="/a/b" />
  ...
select * from some-table where xml = '<b><c>C</c><d>D</d></b>'

C
D
我有一个输出文本的XSLT。例如:

<a>
 <b>
  <c>C</c>
  <d>D</d>
 </b>
</a>
<xsl...>
  <xsl:output method="text" indent="yes"/>
  <xsl:template match="/">
    <xsl:copy-of select="/a/b" />
  ...
select * from some-table where xml = '<b><c>C</c><d>D</d></b>'

...
我想将整个b元素及其子元素复制到一个删除了空格的字符串中,以便生成SQL查询。例如:

<a>
 <b>
  <c>C</c>
  <d>D</d>
 </b>
</a>
<xsl...>
  <xsl:output method="text" indent="yes"/>
  <xsl:template match="/">
    <xsl:copy-of select="/a/b" />
  ...
select * from some-table where xml = '<b><c>C</c><d>D</d></b>'
从xml='CD'的某个表中选择*
此时,的副本正在查找b元素,但删除了所有元素和属性信息,只保留每个元素中的文本内容。我认为这可能与输出类型有关


有什么想法吗?

你的SQL语句把我吓坏了。XML是区分大小写的,如果输入XML和XSLT(包括所有元素、属性和值)的大小写与原始数据库插入中使用的大小写不完全相同,则比较可能会失败

我相信Oracle(某些)和SQL Server(这样认为)都有机制以更为XML友好的方式(例如,使用XPath)对包含XML的列进行查询


你到底想干什么?您的问题似乎比正确转换XSLT更为严重。

对于XSLT来说,这项任务可能有点太具有挑战性了。我能得到的最接近的结果是:

  <xsl:template match="b//*|node()">
    <xsl:copy>
      <xsl:text>&lt;</xsl:text>
      <xsl:value-of select="name()"/>
      <xsl:text>&gt;</xsl:text>
      <xsl:value-of select="text()"/>
      <xsl:apply-templates select="*"/>
      <xsl:text>&lt;/</xsl:text>
      <xsl:value-of select="name()"/>
      <xsl:text>&gt;</xsl:text>
    </xsl:copy>
  </xsl:template>

/
并被称为:

  <xsl:apply-templates select="/a/b/self::*"/>

这将产生以下结果:

 <b>
  <c>C</c>
  <d>D</d>
 </b>

C
D
当元素具有属性时,我的“解决方案”就失效了。如果b有一个属性,那么属性值会被写出。我找不到一种方法来写出属性,当它们出现时;再次遇到


有什么想法吗?

以下是如何做到的:

<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”(而不是原始示例中的“文本”)。它为所有文本节点使用自定义模板来规范化它们内部的空间(删除前导/尾随空格,将多个空格压缩为单个空格)。然后,它使用简单的“标识”模板复制所有节点及其属性。这两个模板都使用特殊模式,以避免干扰XSL的其余部分

不幸的是,XSLT处理器将xsl:template标记内的所有“未知”节点复制到输出文档中,而空格就是这样的节点之一。这就是为什么所有这些模板都需要写在一行中,没有额外的空格


PS尽管如此,我同意在RDBMS中搜索规范化XML有点奇怪。

问题的关键不是XML或查询的内容,而是将XML复制到纯文本。SQL Server 2000(目标数据库)确实支持XML生成,但调用了MSXML解析器。在幕后,这会消耗SQLServer使用的内存(据我所知大约有三分之一)。这是不可取的,因为这将在一个性能关键的系统中结束。体面的、内置的xml支持最初出现在SQLServer2005Good answer中,但我需要一个文本输出。我添加的一点XSLT几乎让我完全理解了这一点,但没有很好地处理属性。最初的任务是用SQL输出XML。谢谢