我有这样的XML:
<process id="Process_1">
<exclusiveGateway id="ExclusiveGateway_03b639w" />
<startEvent id="StartEvent_0nmzsw0" />
<sendTask id="Task_13s9uob"/>
<userTask id="Task_1v0riz3" />
</process>
我需要使用 xslt :
将其转换为此内容<process id="Process_1">
<Gateway type="exclusive" id="ExclusiveGateway_03b639w" />
<Event type="start" id="StartEvent_0nmzsw0" />
<Task type="send" id="Task_13s9uob"/>
<Task type="user" id="Task_1v0riz3" />
</process>
我想我可以使用tokenize
功能,但我不知道如何分隔令牌。
如果有人可以解释这个问题的解决方案,那将非常有用。
感谢。
答案 0 :(得分:2)
假设使用像Saxon 9这样的XSLT 2.0处理器,你可以使用
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[matches(local-name(), '^\p{Ll}+\p{Lu}')]">
<xsl:element name="{replace(local-name(), '^\p{Ll}+', '')}">
<xsl:attribute name="type" select="replace(local-name(), '\p{Lu}.*', '')"/>
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:2)
要在XSLT 1.0中执行此操作,请尝试以下方法:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/process/*">
<xsl:variable name="split" select="string-length(substring-before(translate(name(), 'BCDEFGHIJKLMNOPQRSTUVWXYZ', 'AAAAAAAAAAAAAAAAAAAAAAAAA'), 'A'))" />
<xsl:element name="{substring(name(), $split + 1)}">
<xsl:attribute name="type">
<xsl:value-of select="substring(name(), 1, $split)"/>
</xsl:attribute>
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
请注意,这假设需要根据所示处理根process
元素的所有(且唯一)子元素。
P.S。如果您知道输入XML的结构,那么显式转换单个元素会更加健壮,例如:
<xsl:template match="exclusiveGateway">
<Gateway type="exclusive">
<xsl:apply-templates select="@* | node()"/>
</Gateway>
</xsl:template>