请求参数传入XQuery变量及XSLT使用的问题排查与实现
问题与解决方案
原始XML数据
<A9-ArchaeologicalExcavation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <E53-Place> <Name>asdad</Name> <District/> <Parish/> <Gps> <Latitude/> <Longitude/> </Gps> <A2-StratigraphicVolumeUnit> <Timeline/> <Description/> <Gps> <Latitude/> <Longitude/> </Gps> <S19-EncounterEvent> <Date>2001-11-12</Date> <E24-PhysicalManThing Inventory_number="1"> <E36-VisualItem/> <Order_number>Triangular</Order_number> <Group> <Group-name>Reta</Group-name> <Sub_type>true</Sub_type> </Group> <E3-ConditionState> <E55-Type/> </E3-ConditionState> <E55-Type>Alongado</E55-Type> <Variant>Espessa</Variant> <Typometry Unit="mm"> <Lenght>23</Lenght> <Width>12</Width> <Thickness>5</Thickness> <Body_lenght>19</Body_lenght> <Base_lenght>4</Base_lenght> </Typometry> <Morphology> <Point>true</Point> <Body>false</Body> <Base>Triangular</Base> </Morphology> <Retouch> <Location/> <Mode/> <Amplitude/> <Direction/> <Delineation/> <Orientation/> <Shape/> </Retouch> <Raw_material/> <Observations/> </E24-PhysicalManThing> </S19-EncounterEvent> </A2-StratigraphicVolumeUnit> </E53-Place> </A9-ArchaeologicalExcavation>
当前XQuery代码及问题
现有代码
xquery version "3.0" encoding "UTF-8"; declare variable $fi as xs:integer :=5; declare variable $fi2 as xs:string := "variant"; let $fi:= request:get-parameter("termo", 5) let $fi2 :=request:get-parameter("elementos", "variant") let $x := doc("/db/apps/MegaLOD/arrowheads/arrowheads.xml") let $filter := concat($fi2, " = ", $fi, "") for $arrowheads in $x/arrowheads let $arrowhead_list := (for $arrowhead in $arrowheads/arrowhead[$filter] return $arrowhead) return <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h2>Arrowheads</h2> <xsl:for-each select="A9-ArchaeologicalExcavation/E53-Place/A2-StratigraphicVolumeUnit/S19-EncounterEvent/E24-PhysicalManThing[Variant = 'Espessa']"> <p><xsl:value-of select="@Inventory_number"/></p> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>
存在的问题
- 空白页面原因:直接返回XSLT样式表而非转换后的HTML结果,浏览器无法识别XSLT代码因此显示空白;同时代码中
$x/arrowheads路径错误,原XML根节点是<A9-ArchaeologicalExcavation>,不存在arrowheads节点,这部分逻辑完全无效。 - 变量无法传入XSLT:当前代码未建立XQuery变量与XSLT的传递通道,无法将
$fi和$fi2用于XSLT的筛选逻辑。
修正后的XQuery代码
xquery version "3.0" encoding "UTF-8"; -- 接收GET参数,统一转为字符串适配文本节点值 declare variable $param_term := request:get-parameter("termo", "5"); declare variable $param_element := request:get-parameter("elementos", "Variant"); let $fi := xs:string($param_term) let $fi2 := xs:string($param_element) let $xml_data := doc("/db/apps/MegaLOD/arrowheads/arrowheads.xml") -- 定义带参数的XSLT模板 let $xslt := <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 声明接收XQuery传递的参数 --> <xsl:param name="filter_element"/> <xsl:param name="filter_value"/> <xsl:template match="/"> <html> <body> <h2>Arrowheads</h2> <!-- 动态匹配指定元素和对应值 --> <xsl:for-each select="A9-ArchaeologicalExcavation/E53-Place/A2-StratigraphicVolumeUnit/S19-EncounterEvent/E24-PhysicalManThing[*[local-name() = $filter_element] = $filter_value]"> <p><xsl:value-of select="@Inventory_number"/></p> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet> -- 调用转换函数,传入XML数据和参数 return transform( map { "source-node" : $xml_data, "stylesheet-node" : $xslt, "parameters" : map { "filter_element" : $fi2, "filter_value" : $fi } } )?output
关键修正说明
- 使用
transform()函数:XQuery 3.0及以上版本支持该函数,用于调用XSLT并返回转换后的HTML结果,解决直接返回XSLT导致的空白页面问题。 - 参数传递机制:通过
transform()的parameters参数将XQuery中的$fi和$fi2传递给XSLT,XSLT用<xsl:param>声明接收参数,实现动态筛选。 - 动态节点匹配:XSLT中用
*[local-name() = $filter_element]匹配指定名称的元素,结合$filter_value实现灵活的条件筛选,适配不同查询参数。 - 路径修正:移除无效的
$x/arrowheads路径,使用正确的XML节点结构进行筛选。
内容的提问来源于stack exchange,提问作者Marco Oliveira
相关产品推荐
相关产品推荐

