如何编写XSLT实现CW与xyz的Reference值对比及Record生成?
XSLT转换实现方案
需求概述
- 对比两类
Reference节点值:Item[@uid="CW"]下的ReferenceField[@guid="xyz"]下的Reference
- 匹配值:保留原有Record层级结构输出
- 不匹配值:在
GUID="1"的Record节点下创建新子Record,需维持GUID="1"与GUID="abc"的一一映射 - 输入中
GUID="1"下含3条相关记录,最终需输出4条记录(因ACD未匹配)
输入XML
<Records count="1"> <Record GUID="1"> <Record GUID="abc" > <Record GUID="JK"> <Item uid="CV">TAM</Item> <Item uid="CW"> <Reference>US</Reference> </Item> </Record> </Record> <Record GUID="abc"> <Record GUID="JK"> <Item uid="CV">IISSP</Item> <Item uid="CW"> <Reference>IIORC</Reference> <Reference>ISNAGEP</Reference> </Item> </Record> </Record> <Field guid="xyz"> <Reference>US</Reference> <Reference>ACD</Reference> <Reference>FEAS</Reference> </Field> </Record> </Records>
期望输出XML
<Records> <Record GUID="1"> <Record GUID="abc" > <Record GUID="JK"> <Item uid="CV">TAM</Item> <Item uid="CW"> <Reference>US</Reference> </Item> </Record> </Record> </Record> <Record GUID="1"> <Record GUID="abc"> <Record GUID="JK"> <Item uid="CV">IISSP</Item> <Item uid="CW"> <Reference>IIORC</Reference> <Reference>ISNAGEP</Reference> </Item> </Record> </Record> </Record> <Record GUID="1"> <Record GUID="abc" > <Record GUID="JK"> <Item uid="CV">TAM</Item> <Item uid="CW"> <Reference>ACD</Reference> </Item> </Record> </Record> </Record> <Record GUID="1"> <Record GUID="JK"> <Item uid="CV">TAM</Item> <Item uid="CW"> <Reference>FEAS</Reference> </Item> </Record> </Record> </Records>
XSLT实现代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <!-- 索引Field[@guid='xyz']下的所有Reference值 --> <xsl:key name="field-refs" match="Field[@guid='xyz']/Reference" use="."/> <!-- 匹配根节点Records,重新生成根节点 --> <xsl:template match="Records"> <Records> <!-- 输出原有匹配的Record结构 --> <xsl:apply-templates select="Record[@GUID='1']/Record[@GUID='abc']"/> <!-- 处理Field中未匹配的Reference值 --> <xsl:apply-templates select="Record[@GUID='1']/Field[@guid='xyz']/Reference[not(. = //Item[@uid='CW']/Reference)]"/> </Records> </xsl:template> <!-- 复制原有Record[@GUID='abc']的完整结构 --> <xsl:template match="Record[@GUID='abc']"> <Record GUID="1"> <xsl:copy-of select="."/> </Record> </xsl:template> <!-- 处理未匹配的Reference,生成新的Record结构 --> <xsl:template match="Field[@guid='xyz']/Reference"> <xsl:variable name="tam-abc" select="//Record[@GUID='abc'][Record[@GUID='JK']/Item[@uid='CV']='TAM']"/> <Record GUID="1"> <!-- 保留abc层级(如果存在对应TAM的节点) --> <xsl:if test="$tam-abc"> <xsl:copy-of select="$tam-abc"/> </xsl:if> <!-- 生成JK节点并替换Reference值 --> <Record GUID="JK"> <Item uid="CV">TAM</Item> <Item uid="CW"> <xsl:copy-of select="."/> </Item> </Record> </Record> </xsl:template> <!-- 默认复制模板,处理其他节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码说明
- 键与索引:用
field-refs快速定位Field下的Reference值,简化匹配判断 - 原有结构输出:直接复制
GUID="abc"节点及其子结构,包裹在GUID="1"的Record下 - 未匹配值处理:
- 优先匹配对应
TAM的abc节点,维持层级映射 - 生成新的
JK节点,替换CW下的Reference为当前未匹配的值
- 优先匹配对应
- 默认模板:确保所有未被特殊匹配的节点、属性都被正确复制
内容的提问来源于stack exchange,提问作者Swap
相关产品推荐
相关产品推荐

