XSLT开发需求:校验节点值长度并复制指定值
问题
需要编写XSLT实现以下逻辑:
- 遍历XML中所有
<containedItemIdentification>节点,检查是否存在<IdentificationType>为Type10的<Identification>子节点 - 若存在该节点,且其
<IdentificationValue>的长度≤5,则将该值替换为当前节点所属<LogisticUnitLineItem>下的<serialShippingContainerCode>值 - 若不存在
Type10类型的<Identification>节点,则新增该节点,<IdentificationValue>取值为对应<LogisticUnitLineItem>下的<serialShippingContainerCode>
现有XSLT仅能实现不存在时新增节点的功能,无法处理长度校验替换的逻辑,需完善。
输入XML
<StandardBusinessDocument> <receivingAdvice> <LogisticUnitLineItem> <logisticUnitIdentification> <ContainerCode> <serialShippingContainerCode>121212345890</serialShippingContainerCode> </ContainerCode> </logisticUnitIdentification> <ContainmentLine number="1"> <containedItemIdentification> <gtin>00000000000000</gtin> <Identification> <IdentificationValue>Value1</IdentificationValue> <IdentificationType>Type8</IdentificationType> </Identification> <Identification> <IdentificationValue>4567</IdentificationValue> <IdentificationType>Type10</IdentificationType> </Identification> </containedItemIdentification> </ContainmentLine> <ContainmentLine number="2"> <containedItemIdentification> <gtin>00000000000000</gtin> <Identification> <IdentificationValue>Value2</IdentificationValue> <IdentificationType>Type8</IdentificationType> </Identification> </containedItemIdentification> </ContainmentLine> </LogisticUnitLineItem> <LogisticUnitLineItem> <logisticUnitIdentification> <ContainerCode> <serialShippingContainerCode>1309089485</serialShippingContainerCode> </ContainerCode> </logisticUnitIdentification> <ContainmentLine number="1"> <containedItemIdentification> <gtin>00000000000000</gtin> <Identification> <IdentificationValue>86432509</IdentificationValue> <IdentificationType>Type10</IdentificationType> </Identification> </containedItemIdentification> </ContainmentLine> <ContainmentLine number="2"> <containedItemIdentification> <gtin>00000000000000</gtin> <Identification> <IdentificationValue>6867</IdentificationValue> <IdentificationType>Type10</IdentificationType> </Identification> </containedItemIdentification> </ContainmentLine> </LogisticUnitLineItem> </receivingAdvice> </StandardBusinessDocument>
期望输出XML
<StandardBusinessDocument> <receivingAdvice> <LogisticUnitLineItem> <logisticUnitIdentification> <ContainerCode> <serialShippingContainerCode>121212345890</serialShippingContainerCode> </ContainerCode> </logisticUnitIdentification> <ContainmentLine number="1"> <containedItemIdentification> <gtin>00000000000000</gtin> <Identification> <IdentificationValue>Value1</IdentificationValue> <IdentificationType>Type8</IdentificationType> </Identification> <Identification> <IdentificationValue>121212345890</IdentificationValue> <IdentificationType>Type10</IdentificationType> </Identification> </containedItemIdentification> </ContainmentLine> <ContainmentLine number="2"> <containedItemIdentification> <gtin>00000000000000</gtin> <Identification> <IdentificationValue>Value2</IdentificationValue> <IdentificationType>Type8</IdentificationType> </Identification> <Identification> <IdentificationValue>121212345890</IdentificationValue> <IdentificationType>Type10</IdentificationType> </Identification> </containedItemIdentification> </ContainmentLine> </LogisticUnitLineItem> <LogisticUnitLineItem> <logisticUnitIdentification> <ContainerCode> <serialShippingContainerCode>1309089485</serialShippingContainerCode> </ContainerCode> </logisticUnitIdentification> <ContainmentLine number="1"> <containedItemIdentification> <gtin>00000000000000</gtin> <Identification> <IdentificationValue>86432509</IdentificationValue> <IdentificationType>Type10</IdentificationType> </Identification> </containedItemIdentification> </ContainmentLine> <ContainmentLine number="2"> <containedItemIdentification> <gtin>00000000000000</gtin> <Identification> <IdentificationValue>1309089485</IdentificationValue> <IdentificationType>Type10</IdentificationType> </Identification> </containedItemIdentification> </ContainmentLine> </LogisticUnitLineItem> </receivingAdvice> </StandardBusinessDocument>
现有XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:strip-space elements="*"/> <xsl:output indent="yes"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="Identification[last()][not(contains(IdentificationType, 'Type10'))]"> <xsl:copy-of select="."/> <xsl:copy> <IdentificationValue> <xsl:value-of select="ancestor::LogisticUnitLineItem/logisticUnitIdentification/ContainerCode/serialShippingContainerCode"/> </IdentificationValue> <IdentificationType>Type10</IdentificationType> </xsl:copy> </xsl:template> </xsl:stylesheet>
解决方案
以下是完善后的XSLT代码,可同时处理修改和新增逻辑:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:strip-space elements="*"/> <xsl:output indent="yes"/> <!-- 默认身份转换模板,保留所有未匹配的节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配需要修改的Type10节点:值长度≤5时替换 --> <xsl:template match="Identification[IdentificationType='Type10' and string-length(IdentificationValue) ≤ 5]"> <xsl:copy> <IdentificationValue> <xsl:value-of select="ancestor::LogisticUnitLineItem/logisticUnitIdentification/ContainerCode/serialShippingContainerCode"/> </IdentificationValue> <xsl:copy-of select="IdentificationType"/> </xsl:copy> </xsl:template> <!-- 给没有Type10节点的containedItemIdentification新增节点 --> <xsl:template match="containedItemIdentification[not(Identification/IdentificationType='Type10')]"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> <!-- 新增Type10的Identification节点 --> <Identification> <IdentificationValue> <xsl:value-of select="ancestor::LogisticUnitLineItem/logisticUnitIdentification/ContainerCode/serialShippingContainerCode"/> </IdentificationValue> <IdentificationType>Type10</IdentificationType> </Identification> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 默认模板:保留所有原有节点和属性,确保非目标节点不受影响
- 修改逻辑:精准匹配
IdentificationType为Type10且IdentificationValue长度≤5的节点,替换其值为所属<LogisticUnitLineItem>下的<serialShippingContainerCode> - 新增逻辑:匹配所有未包含
Type10类型<Identification>节点的<containedItemIdentification>,在其末尾新增符合要求的Type10节点
内容的提问来源于stack exchange,提问作者CHAR
相关产品推荐
相关产品推荐

