我想用XSLT提取字符串的值,它是XML结构的一部分。因此,我需要将冒号前面的单词作为节点名称,并将冒号后面的单词作为该节点的值。节点名称在每个文档中都是相同的,但值是不同的,所以我考虑使用通配符来提取值,但我不知道如何做到这一点。你能帮我个忙吗?
<mail>
<body>
Fruit: apple
Vagetable: potato
Animal: dog
</body>
</mail>
所以结果应该是这样的:
<mail>
<Fruit>apple</Fruit>
<Vagetable>potato</Vagetable>
<Animal>dog</Animal>
</mail>
我正在使用XSLT 2.0
你可以这样看:
XSLT 2.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"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="mail">
<xsl:copy>
<xsl:for-each select="tokenize(body, ' ')[normalize-space()]">
<xsl:element name="{substring-before(., ': ')}">
<xsl:value-of select="substring-after(., ': ')"/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这是另一个:
<xsl:template match="mail">
<xsl:copy>
<xsl:analyze-string select="body" regex="^(.+): (.+)$" flags="m">
<xsl:matching-substring>
<xsl:element name="{regex-group(1)}">
<xsl:value-of select="regex-group(2)"/>
</xsl:element>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:copy>
</xsl:template>
注意,两者都假定每个名称/值对的第一部分是有效的元素名称。
你可以使用tokenize函数在模板匹配mailnormalizebodytext before
<xsl:template match="mail">
<xsl:variable name="strvalue" select="replace(./body/text(), '(^ns+)|(ns+$)', '')"/>
<xsl:variable name="strvalue" select="replace($strvalue, 'ns+', '#')"/>
<xsl:copy>
<xsl:for-each select="tokenize($strvalue, '#')">
<xsl:variable select="tokenize(., ': ')" name="values"/>
<!--<xsl:element name='{$values[1]}'>-->
<xsl:element name="{replace($values[1], '[^w]', '_')}">
<xsl:value-of select="$values[2]"/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
这一部分<xsl:variable name="strvalue" select="replace(./body/text(), '(^ns+)|(ns+$)', '')"/>
<xsl:variable name="strvalue" select="replace($strvalue, 'ns+', '#')"/>
将正文文本转换为字符串,其中行以#分隔,并将其保存在变量中。来自主体的字符串看起来像
Fruit: apple#Vagetable: potato#Animal: dog