我有一个带有以下标记和数据的xml文件main.xml。
main.xml
<xml>
<content>
<para>
This is a para.
</para>
<sub para>
This is para.
</sub para>
</content>
</xml>
我有另一个xml文件keyword.xml,其中包含我们需要在xml上面找到任何位置的关键字列表,并替换关键字值。
keyword.xml
<xml>
<keywordList>
<keyword>
<value>para</value>
<replace> paragraph </replace>
</keyword>
<keyword>
<value>is</value>
<replace>IS</replace>
</keyword>
</xml>
我们可以在xslt中执行此操作,以便输出应为
output
<xml>
<content>
<para>
This IS a paragraph.
</para>
<sub para>
This IS paragraph.
</sub para>
</content>
</xml>
答案 0 :(得分:1)
尝试以下
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="keywords" select="document('keyword.xml')"/>
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:analyze-string select="." regex="[A-Za-z]+">
<xsl:matching-substring>
<xsl:variable name="repl" select="$keywords//keyword[value = current()]"/>
<xsl:choose>
<xsl:when test="$repl">
<xsl:value-of select="$repl/replace"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="current()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="current()"/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
请注意,para的replace值包含新单词周围的空格,因此还有其他空格:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<content>
<para>
This IS a paragraph .
</para>
<subpara>
This IS paragraph .
</subpara>
</content>
</xml>
答案 1 :(得分:0)
这是一个XSLT 1.0解决方案(当然,也可以与XSLT 2.0一起使用):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:params xml:space="preserve">
<pattern>
<old>para</old>
<new> paragraph </new>
</pattern>
<pattern>
<old> is </old>
<new> IS </new>
</pattern>
</my:params>
<xsl:variable name="vrtfPats">
<xsl:for-each select="document('')/*/my:params/*">
<xsl:sort select="string-length(old)"
data-type="number" order="descending"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="vPats" select=
"ext:node-set($vrtfPats)/*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()" name="multiReplace" priority="2">
<xsl:param name="pText" select="."/>
<xsl:param name="pPatterns" select="$vPats"/>
<xsl:if test= "string-length($pText) >0">
<xsl:variable name="vPat" select=
"$vPats[starts-with($pText, old)][1]"/>
<xsl:choose>
<xsl:when test="not($vPat)">
<xsl:copy-of select="substring($pText,1,1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$vPat/new/node()"/>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="multiReplace">
<xsl:with-param name="pText" select=
"substring($pText,
1 + not($vPat) + string-length($vPat/old/node())
)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档(更正为格式良好):
<xml>
<content>
<para>
This is a para.
</para>
<sub_para>
This is para.
</sub_para>
</content>
</xml>
产生了想要的正确结果:
<xml>
<content>
<para>
This IS a paragraph .
</para>
<sub_para>
This IS paragraph .
</sub_para>
</content>
</xml>
解释:逐字符扫描文本,文本中该位置开始的最长目标字符串将替换为其指定的替换。