xml - XSLT - 如何根据分隔符拆分字符串并将值分配给多个属性
问题描述
输入 XML:
<testng-results>
<suite>
<test>
<class>
<test-method status="PASS" description="Test_ID:123,Test_Name:Test ABC,Product:Product ABC"></test-method>
<test-method status="PASS" description="Test_ID:456,Test_Name:Test XYZ,Product:Product XYZ"></test-method>
</class>
</test>
</suite>
</testng-results>
我当前的 XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<Suite>
<xsl:for-each select="testng-results/suite/test/class/test-method">
<test>
<xsl:attribute name="status">
<xsl:value-of select="@status" />
</xsl:attribute>
<xsl:attribute name="Test_ID">
<xsl:value-of select="" />
</xsl:attribute>
<xsl:attribute name="Test_Name">
<xsl:value-of select="" />
</xsl:attribute>
<xsl:attribute name="Product">
<xsl:value-of select="" />
</xsl:attribute>
</test>
</xsl:for-each>
</Suite>
预期输出.XML:
<?xml version="1.0" encoding="UTF-8"?>
<Suite>
<test status="PASS" Test_ID="123" Test_Name="Test ABC" Product="Product ABC" />
<test status="PASS" Test_ID="456" Test_Name="Test XYZ" Product="Product XYZ" />
</Suite>
我必须从“描述”值中获取字符串并拆分这些值以生成输出 xml。
我读过 XSLT 2.0 更好地配备了字符串标记化功能。但是,我只能使用 XSLT 1.0。
解决方案
我提出这种方法。它相当粗糙,但可以肯定,因为它仅依赖于标准 XSLT 元素和函数:
(为了标记化,它实现了一个递归算法。)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="/">
<Suite>
<xsl:apply-templates select="testng-results/suite/test/class/test-method"></xsl:apply-templates>
</Suite>
</xsl:template>
<xsl:template match="test-method">
<test>
<xsl:call-template name="tokenize-to-attrs">
<xsl:with-param name="s" select="@description"/>
</xsl:call-template>
</test>
</xsl:template>
<xsl:template name="tokenize-to-attrs">
<xsl:param name="s"/>
<xsl:variable name="pair" select="substring-before($s, ',')"/>
<xsl:if test="$pair">
<xsl:call-template name="to-attr">
<xsl:with-param name="s" select="$pair"/>
</xsl:call-template>
<xsl:call-template name="tokenize-to-attrs">
<xsl:with-param name="s" select="substring-after($s, ',')"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="not($pair)">
<xsl:call-template name="to-attr">
<xsl:with-param name="s" select="$s"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="to-attr">
<xsl:param name="s"/>
<xsl:variable name="name" select="substring-before($s, ':')"/>
<xsl:variable name="value" select="substring-after($s, ':')"/>
<xsl:attribute name="{$name}">
<xsl:value-of select="$value"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
推荐阅读
- gitlab - 如何从另一个 Gitlab 管道运行特定的 Gitlab 作业?
- c# - 如何在 C# 中将“MMyy”格式化为“MM/yyyy”
- python - pymongo.errors.ServerSelectionTimeoutError:localhost:27017:[WinError 10061]No connection could be made because the target machine主动拒绝它
- node.js - 第一次登录后Bcrypt总是假的
- php - Yii2框架中如何执行迁移?
- amazon-web-services - AWS S3 静态网站托管重定向未针对通过 CloudFront 分配的请求激活
- python - Webscraping - 如果“Nontype”对象没有属性,则添加 If 语句
- python - 如何从外部调用的 Python 函数在 Qlabel 中显示消息
- kubernetes - Liveness/Readiness 探针如何与 pod 通信?
- amazon-web-services - 使用 lambda 函数的 AWS S3 存储桶索引