我有以下XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<A>
<B>Dvortsovaya pl 2</B>
<B>Inzhenernaya ul 4</B>
<B>xyzul</B>
</A>
我想针对关键字列表测试<B>
的内容(在这种情况下:'ul','pl','nab')并添加属性type='adress'
如果有关键字存在。
所以预期的XML输出如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<A>
<B type='adress'>Dvortsovaya pl 2</B>
<B type='adress'>Inzhenernaya ul 4</B>
<B>xyzul</B>
</A>
由于关键字列表可能会有所不同,我正在尝试编写一个普通的模板,它从变量中的列表中获取关键字。我尝试使用'循环'模板实现这一点,这显然不起作用:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()" priority="-1">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="adressKeywords">
<item n="1">ul</item>
<item n="2">pl</item>
<item n="3">nab</item>
</xsl:variable>
<xsl:template match="B">
<xsl:call-template name="addAttribute">
<xsl:with-param name="start" select="1"/>
<xsl:with-param name="end" select="count($adressKeywords/item)"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="addAttribute">
<xsl:param name="start"/>
<xsl:param name="end"/>
<xsl:variable name="text">
<xsl:value-of select="normalize-space(.)"/>
</xsl:variable>
<xsl:if test="$start <= $end">
<xsl:variable name="reg">(^|\W)<xsl:value-of select="$adressKeywords/item[@n=$start]"
/>($|\W)</xsl:variable>
<xsl:choose>
<xsl:when test=" matches($text, $reg)">
<xsl:copy>
<xsl:attribute name="value">adress</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:if test="$start <= $end">
<xsl:call-template name="addAttribute">
<xsl:with-param name="start">
<xsl:value-of select="$start+1"/>
</xsl:with-param>
<xsl:with-param name="end">
<xsl:value-of select="$end"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
我知道怎样才能得到结果(如果可能的话......)? 谢谢!
答案 0 :(得分:2)
我只是为那些匹配替代关键字的B
元素编写模板:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:param name="adressKeywords">
<item n="1">ul</item>
<item n="2">pl</item>
<item n="3">nab</item>
</xsl:param>
<xsl:variable name="regex" select="concat('(^|\W)(', string-join($adressKeywords/item, '|'), ')($|\W)')"/>
<xsl:template match="B[matches(., $regex)]">
<B type="address">
<xsl:apply-templates select="@* | node()"/>
</B>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
使其更简单,为A / *添加模板,检查是否存在关键字并添加@type:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="adressKeywords">
<item>ul</item>
<item>pl</item>
<item>nab</item>
</xsl:variable>
<xsl:template match="/A">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="A/*[true() = (for $var in $adressKeywords/* return if(contains(., $var)) then true() else false())]">
<xsl:copy>
<xsl:attribute name="type">adress</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>