2008-11-25 98 views
1

我有一個XML定義,其中包含具有子元素的元素。例如:使用XML和XSLT生成SQL

<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="https://stackoverflow.com/a/b" /> 
    ... 

我想將整個b元素及其子元素複製到刪除空白字符串中,以便可以生成SQL查詢。例如:

select * from some-table where xml = '<b><c>C</c><d>D</d></b>' 

目前複製的是找到B元素,但脫落的所有元素和屬性信息,只留下在每一個文本內容。我認爲這可能與輸出類型有關。

任何想法?

回答

-1

這裏是它是如何做:

<xsl:output method="xml" /> 

<xsl:template match="/"><xsl:apply-templates select="https://stackoverflow.com/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節點使用自定義模板來標準化它們內部的空間(刪除前導/尾隨空白,將多個空間壓縮爲單個空間)。然後,它使用簡單的「身份」模板來複制所有節點及其屬性。兩個模板都使用特殊模式來避免干擾XSL的其餘部分。

不幸的是,XSLT處理器將xsl:template標籤內的所有「未知」節點複製到輸出文檔中,而空格就是這樣的節點之一。這就是爲什麼所有這些模板都需要用一行書寫而沒有多餘空格的原因。

PS雖然,我同意在RDBMS中搜索標準化的XML有點奇怪。

1

您的SQL語句讓我害怕。 XML區分大小寫,如果輸入的XML和XSLT(包括所有元素,屬性和值)沒有與原始數據庫插入中使用的完全一樣,那麼您的比較可能會失敗。我相信Oracle(某些)和SQL Server(認爲是這樣)都有機制以更友好的方式(例如,使用XPath)對包含XML的列執行查詢。

你究竟想要做什麼?您的問題似乎比讓這個XSLT正確轉換更深刻。

+0

問題的關鍵不在於XML或查詢的內容,而是實際上將XML複製爲純文本。 – 2008-11-25 22:55:58

+0

SQL Server 2000(目標數據庫)不支持XML生成,但調用MSXML分析器。在幕後,這具有吞噬SQL Server使用的內存的作用(大約三分之一我被告知)。這是不可取的,因爲這將在性能關鍵系統中結束。 – 2008-11-25 22:59:49

1

對於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="https://stackoverflow.com/a/b/self::*"/> 

這將產生以下:

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

在哪裏我的「解決方案」倒下的是元素時有屬性。如果b有一個屬性,則屬性值將被寫出。我無法找到寫出屬性的方式,當他們遇到......重新遇到......

任何想法?