如何使用XSLT基于前序节点键值复制XML中Delivery类型Stop节点
解决方案
你原有代码存在两处核心问题:
- 使用
<xsl:value-of>获取Delivery节点只会返回文本内容,无法复制完整的节点结构,应该用<xsl:copy-of> - 模板嵌套了多余的
<xsl:copy>标签,会导致Pickup节点重复嵌套,另外你定义的Key如果是用于关联Pickup和Delivery的Order,需要调整匹配规则指向Delivery节点。
如果你的需求是将同个Stops下所有StopType=Delivery的节点全量复制到Pickup节点内的CopiedStop下,可直接使用以下调整后的XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="1.0"> <!-- 若需要按Order关联匹配Delivery,可使用该Key,匹配时去掉Delivery的ShipperRef前缀R --> <xsl:key name="deliveryByOrderRef" match="Stop[StopType='Delivery']/OrderNums" use="concat(substring(OrderNum/@ShipperRef,2),'|',../../CalcDueDate,'|',../../StopNumber)"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()" /> </xsl:copy> </xsl:template> <xsl:template match="Stop[StopType='Pickup']"> <xsl:copy> <!-- 复制Pickup原有所有属性和子节点 --> <xsl:apply-templates select="@* | node()"/> <CopiedStop> <!-- 全量复制同层级所有Delivery类型Stop,与你给出的预期输出完全匹配 --> <xsl:copy-of select="../Stop[StopType='Delivery']"/> <!-- 若需要按Key关联匹配对应Delivery,将上面一行替换为下面的逻辑即可 <xsl:for-each select="OrderNums"> <xsl:copy-of select="key('deliveryByOrderRef', concat(OrderNum/@ShipperRef,'|',../../CalcDueDate,'|',../../StopNumber))/parent::Stop"/> </xsl:for-each> --> </CopiedStop> </xsl:copy> </xsl:template> </xsl:stylesheet>
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

