我正在使用 XSLT 将一个 XML 文件转换为另一个 XML 文件。 XML 文件具有如下元素:
<Course>
<ID>1001</ID>
<Seats>10</Seats>
<Description>Department: CS , Faculty: XYZ</Description>
</Course>
现在,当我生成如下所示的新 XML 文件时,XSLT 中是否有任何方法:
<Course>
<ID>1001</ID>
<Seats>10</Seats>
<Department> CS </Department>
<Faculty> XYZ</Faculty>
</Course>
也就是说,我想将 Description 元素拆分为两个不同的元素 Department 和 Faculty,它们基本上是用逗号分隔的内容。我使用 XMLspy 来编写 XSLT。
提前谢谢您。
最佳答案
这是一种可能的 XSLT2 解决方案,它基于特定于 Description 元素的模板中的身份转换和 tokenize 字符串函数。
总体思路是首先将描述字符串拆分为“,”,然后将每个结果子字符串拆分为“:”,仅选择最后一部分。
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Description">
<xsl:variable name="tokens" select="fn:tokenize(text(),',')"/>
<xsl:element name="Department"><xsl:value-of select="fn:normalize-space(fn:tokenize($tokens[1],':')[2])"/></xsl:element>
<xsl:element name="Faculty"><xsl:value-of select="fn:normalize-space(fn:tokenize($tokens[2],':')[2])"/></xsl:element>
</xsl:template>
</xsl:stylesheet>
最后一步调用标准化空间函数,以去除前导/尾随空格;如果没有必要,请忽略该部分。
买者自负:这里假设描述文本的格式是固定的(即部门和学院始终以相同的顺序出现。)此外,假设描述元素中既不出现“:”也不出现“,”文本。
上面的转换产生了预期的结果:
<?xml version="1.0" encoding="UTF-8"?><Course>
<ID>1001</ID>
<Seats>10</Seats>
<Department>CS</Department>
<Faculty>XYZ</Faculty>
</Course>
请注意,在一段纯文本中包含结构化信息并不完全是充分利用 XML,XML 完全与结构有关,但我猜格式不是您可以控制的。
根据评论更新:
基于regular expression的更强大的替代解决方案下面列出了匹配。在这种情况下,只有与 Department、Faculty 模式匹配的 Description 元素被重写;否则原始描述元素将被传递:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Description">
<xsl:analyze-string select="." regex="\s*Department:\s*(.+)\s*,\s*Faculty:\s*(.+)\s*">
<xsl:matching-substring>
<xsl:element name="Department"><xsl:value-of select="regex-group(1)"/></xsl:element>
<xsl:element name="Faculty"><xsl:value-of select="regex-group(2)"/></xsl:element>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:element name="Description"><xsl:copy/></xsl:element>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
这里的关键思想是使用 xsl:analyze-string
通过 XSLT regular expression 进行测试如果找到预期的模式,并捕获这种情况下的相应值。如果未找到匹配项,则复制 Description 元素的原始内容。
注意:将其与根元素集成作为读者的练习(因为 OP 示例未显示 Course 元素适合的位置)。
关于xml - 使用 XSLT 根据 XML 中的文本拆分元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14528240/