如何使用XSLT2.0自定义分隔符提取XML同名标签多值
问题
我有一个XML文件,其中可能包含多个名称相同但属性值不同的标签。当我使用XSLT提取这些标签的值时,结果会以空格分隔所有值。但我希望使用逗号或竖线等其他分隔符来分隔这些值,请问能否实现该需求?
示例XML
<?xml version='1.0' encoding='UTF-8'?> <wd:Report_Data xmlns:wd="urn:com.workday.report/CR_INT_Persona_Request"> <wd:Report_Entry> <wd:Request_For_Worker wd:Descriptor="Jennifer Sauvigne"> <wd:ID wd:type="WID">455b87a53cbe01005867fa601a4b0000</wd:ID> <wd:ID wd:type="Employee_ID">10001557</wd:ID> </wd:Request_For_Worker> <wd:Persona_Request_Reason wd:Descriptor="Agency Transfer"> <wd:ID wd:type="WID">5f7f70c485129020102b543c324a0001</wd:ID> </wd:Persona_Request_Reason> <wd:Request_Persona_Type wd:Descriptor="FINS"> <wd:ID wd:type="WID">5f7f70c485129020102b543c324a0002</wd:ID> </wd:Request_Persona_Type> <wd:FINS_or_PSA_Persona_Requested wd:Descriptor="P013 - Accountant (Which FINS Persona is needed?)"> <wd:ID wd:type="WID">ae11cc7534c0101560351fbf14da0000</wd:ID> <wd:ID wd:type="Question_Multiple_Choice_Answer_ID" >QUESTION_MULTIPLE_CHOICE_ANSWER-6-ae11cc7534c0101560351fbf14da0000</wd:ID> </wd:FINS_or_PSA_Persona_Requested> <wd:FINS_Persona_Requested wd:Descriptor="P013 - Accountant (Which FINS Persona is needed?)"> <wd:ID wd:type="WID">ae11cc7534c0101560351fbf14da0000</wd:ID> <wd:ID wd:type="Question_Multiple_Choice_Answer_ID" >QUESTION_MULTIPLE_CHOICE_ANSWER-6-ae11cc7534c0101560351fbf14da0000</wd:ID> </wd:FINS_Persona_Requested> <wd:Request_Persona_Companies wd:Descriptor="CO00002 - Wunderman Thompson Data Consulting LLC"> <wd:ID wd:type="WID">5f7f70c485129020102b543c324a0005</wd:ID> </wd:Request_Persona_Companies> <wd:Request_Persona_Companies wd:Descriptor="CO00001 - Absolute Color LLC"> <wd:ID wd:type="WID">5f7f70c485129020102b543c324a0004</wd:ID> </wd:Request_Persona_Companies> <wd:Request_Persona_BU_Hierarchies wd:Descriptor="Msft Client Coord"> <wd:ID wd:type="WID">5f7f70c485129020102b543c324a0007</wd:ID> </wd:Request_Persona_BU_Hierarchies> <wd:Request_Persona_BU_Hierarchies wd:Descriptor="MSC WW HQ"> <wd:ID wd:type="WID">5f7f70c485129020102b543c324a0006</wd:ID> </wd:Request_Persona_BU_Hierarchies> </wd:Report_Entry> </wd:Report_Data>
期望输出XML
<?xml version="1.0" encoding="UTF-8"?> <Request xmlns:wd="urn:com.workday.report/CR_INT_Persona_Request"> <Persona>P013 - Accountant (Which FINS Persona is needed?)</Persona> <Persona_Companies>CO00002 - Wunderman Thompson Data Consulting LLC,CO00001 - Absolute Color LLC</Persona_Companies> <Persona_BU_hierarchies>Msft Client Coord,MSC WW HQ</Persona_BU_hierarchies> </Request>
解决方案
完全可以实现,根据你使用的XSLT版本,有两种常用方法:
方法1:使用XSLT 2.0+的string-join()函数
XSLT 2.0及以上版本提供了string-join()函数,可直接将节点序列用指定分隔符拼接,写法简洁高效:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wd="urn:com.workday.report/CR_INT_Persona_Request"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <xsl:template match="/wd:Report_Data"> <Request> <Persona> <xsl:value-of select="wd:Report_Entry/wd:FINS_Persona_Requested/@wd:Descriptor"/> </Persona> <Persona_Companies> <xsl:value-of select="string-join(wd:Report_Entry/wd:Request_Persona_Companies/@wd:Descriptor, ',')"/> </Persona_Companies> <Persona_BU_hierarchies> <xsl:value-of select="string-join(wd:Report_Entry/wd:Request_Persona_BU_Hierarchies/@wd:Descriptor, ',')"/> </Persona_BU_hierarchies> </Request> </xsl:template> </xsl:stylesheet>
方法2:兼容XSLT 1.0的模板拼接
如果你的环境仅支持XSLT 1.0,可通过模板遍历节点,手动处理分隔符(避免末尾多出分隔符):
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wd="urn:com.workday.report/CR_INT_Persona_Request"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <xsl:template match="/wd:Report_Data"> <Request> <Persona> <xsl:value-of select="wd:Report_Entry/wd:FINS_Persona_Requested/@wd:Descriptor"/> </Persona> <Persona_Companies> <xsl:apply-templates select="wd:Report_Entry/wd:Request_Persona_Companies"/> </Persona_Companies> <Persona_BU_hierarchies> <xsl:apply-templates select="wd:Report_Entry/wd:Request_Persona_BU_Hierarchies"/> </Persona_BU_hierarchies> </Request> </xsl:template> <xsl:template match="wd:Request_Persona_Companies"> <xsl:value-of select="@wd:Descriptor"/> <xsl:if test="position() != last()"> <xsl:text>,</xsl:text> </xsl:if> </xsl:template> <xsl:template match="wd:Request_Persona_BU_Hierarchies"> <xsl:value-of select="@wd:Descriptor"/> <xsl:if test="position() != last()"> <xsl:text>,</xsl:text> </xsl:if> </xsl:template> </xsl:stylesheet>
说明
- 两种方法都能实现将多个同标签的属性值用指定分隔符拼接的需求,可根据XSLT版本选择对应方案。
- 若需要其他分隔符(如竖线
|),只需修改string-join的第二个参数,或模板中的<xsl:text>,</xsl:text>内容即可。
内容的提问来源于Stack Exchange,提问作者VJain
相关产品推荐
相关产品推荐

