XSLT中存储元素所有值到变量并校验替换managerID值的实现方案
XSLT中存储元素所有值到变量并校验替换managerID值的实现方案
嗨,我来帮你搞定这个XML转换需求!你的需求很明确:把所有employeeID的值收集起来,逐个检查managerID,如果它的值不在任何一个employeeID里,就替换成Not Found。用XSLT就能轻松实现,下面是具体方案:
核心思路
先用XSLT的<xsl:key>把所有employeeID的值做个索引,这样后续判断的时候不用反复遍历整个文档,效率更高。然后通过模板匹配专门处理managerID元素,根据索引结果决定输出内容,其他节点保持原样。
完整XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wd="urn:com.workday.report/bsvc"> <!-- 定义索引,把所有employeeID的文本值作为检索键 --> <xsl:key name="employee-ids" match="wd:employeeID" use="text()"/> <!-- 身份模板:原样复制所有未被专门匹配的节点,保证原有结构不变 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 专门处理managerID的模板 --> <xsl:template match="wd:managerID"> <wd:managerID> <xsl:choose> <!-- 检查当前managerID的值是否在employeeID索引中存在 --> <xsl:when test="key('employee-ids', text())"> <!-- 存在则保留原内容 --> <xsl:value-of select="text()"/> </xsl:when> <xsl:otherwise> <!-- 不存在则替换为"Not Found" --> <xsl:text>Not Found</xsl:text> </xsl:otherwise> </xsl:choose> </wd:managerID> </xsl:template> </xsl:stylesheet>
代码关键点解释
- 命名空间绑定:你的XML用了
wd前缀的命名空间,所以XSLT里必须声明完全相同的xmlns:wd,否则会匹配不到目标元素。 <xsl:key>索引:创建一个名为employee-ids的索引,把所有wd:employeeID的文本值作为检索键,后续用key()函数能快速判断某个值是否存在。- 身份模板:这是XSLT的基础模板,会原样复制所有没有被专门模板匹配的节点,保证XML的其他结构、属性和内容都不受影响。
- managerID处理逻辑:专门匹配
wd:managerID元素,通过<xsl:choose>做判断:如果索引能找到对应值就保留原内容,否则替换成Not Found。
效果示例
输入XML(你的示例内容)
<wd:Report_Data xmlns:wd="urn:com.workday.report/bsvc"> <wd:Report_Entry> <wd:employeeID>EMPLOYEE1</wd:employeeID> <wd:managerID>EMPLOYEE5</wd:managerID> </wd:Report_Entry> <wd:Report_Entry> <wd:employeeID>EMPLOYEE2</wd:employeeID> <wd:managerID>EMPLOYEE6</wd:managerID> </wd:Report_Entry> <wd:Report_Entry> <wd:employeeID>EMPLOYEE6</wd:employeeID> <wd:managerID>EMPLOYEE17</wd:managerID> </wd:Report_Entry> <wd:Report_Entry> <wd:employeeID>EMPLOYEE17</wd:employeeID> <wd:managerID>EMPLOYEE20</wd:managerID> </wd:Report_Entry> </wd:Report_Data>
转换后输出XML
<wd:Report_Data xmlns:wd="urn:com.workday.report/bsvc"> <wd:Report_Entry> <wd:employeeID>EMPLOYEE1</wd:employeeID> <wd:managerID>Not Found</wd:managerID> </wd:Report_Entry> <wd:Report_Entry> <wd:employeeID>EMPLOYEE2</wd:employeeID> <wd:managerID>EMPLOYEE6</wd:managerID> </wd:Report_Entry> <wd:Report_Entry> <wd:employeeID>EMPLOYEE6</wd:employeeID> <wd:managerID>EMPLOYEE17</wd:managerID> </wd:Report_Entry> <wd:Report_Entry> <wd:employeeID>EMPLOYEE17</wd:employeeID> <wd:managerID>Not Found</wd:managerID> </wd:Report_Entry> </wd:Report_Data>
可以看到,EMPLOYEE5和EMPLOYEE20因为不在任何employeeID里,被替换成了Not Found,其他符合条件的managerID则保留了原值。
备注:内容来源于stack exchange,提问作者Rohit Tandon
相关产品推荐
相关产品推荐

