我的XML源指定linkGrp
中的交叉引用。基于那些
@target属性指定的交叉引用,我需要分组
s
元素的值。如果target属性包含一对一
参考,我的代码运作良好如下:
<DIV>
<div id="e">
<s id="e1">AAAAA</s>
<s id="e2">BBBBB</s>
<s id="e3">CCCCC</s>
</div>
<div id="fr">
<s id="fr1">DDDDD</s>
<s id="fr2">EEEEE</s>
<s id="fr3">FFFFF</s>
</div>
<linkGrp type="alignment" domains="e fr">
<link target="#e1 #fr1"/>
<link target="#e2 #fr3"/>
<link target="#e3 #fr2"/>
</linkGrp>
</DIV>
我得到的HTML输出是:
*AAAAA
DDDDD
*BBBBB
FFFFF
*CCCCC
EEEEE
要获得此结果,我使用以下XSLT代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="linkId" match="s" use="@id"/>
<xsl:template match="/DIV">
<html>
<head>
<title>Test</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="link">
<ul>
<li>
<xsl:value-of select="key('linkId',substring-before(substring-after(@target, '#'), ' '))"/>
<br/>
<xsl:value-of select="key('linkId',substring-after(@target, ' #'))"/>
</li>
</ul>
</xsl:template>
<xsl:template match="div"/>
<xsl:template match="s"/>
<xsl:template match="*">
<xsl:message terminate="no">
WARNING: Unmatched element: <xsl:value-of select="name()"/>
</xsl:message>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
但是,当我在link
元素中为一个@target添加更多交叉引用时,我的XSLT代码效果不佳:
<DIV>
<div id="e">
<s id="e1">AAAAA</s>
<s id="e2">BBBBB</s>
<s id="e3">CCCCC</s>
</div>
<div id="fr">
<s id="fr1">DDDDD</s>
<s id="fr2">EEEEE</s>
<s id="fr3">FFFFF</s>
</div>
<linkGrp type="alignment" domains="e fr">
<link target="#e1 #fr1"/>
<link target="#e2 #fr3 #fr1 #fr2"/>
<link target="#e3 #fr2 #fr3"/>
</linkGrp>
</DIV>
在XML源代码中有多个交叉引用,我的XSLT代码无法获取
任何比赛。我需要我的代码来检索@target
中指定的所有匹配项
属性。任何人都可以在我的XSLT代码中指出错误或提供替代方案
溶液
答案 0 :(得分:0)
使用xslt-1.0,您可以使用递归模板调用来拆分ID。 尝试这样的事情:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="linkId" match="s" use="@id"/>
<xsl:template match="/DIV">
<html>
<head>
<title>Test</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="link">
<ul>
<li>
<xsl:call-template name="findtarget">
<xsl:with-param name="targets" select="@target" />
</xsl:call-template>
</li>
</ul>
</xsl:template>
<xsl:template name="findtarget">
<xsl:param name="targets" />
<xsl:choose>
<xsl:when test="contains($targets, ' ')">
<xsl:call-template name="findtarget">
<xsl:with-param name="targets" select="substring-before($targets,' ')" />
</xsl:call-template>
<br/>
<xsl:call-template name="findtarget">
<xsl:with-param name="targets" select="substring-after($targets,' ')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="key('linkId',substring-after($targets, '#'))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="div"/>
<xsl:template match="s"/>
<xsl:template match="*">
<xsl:message terminate="no">
WARNING: Unmatched element: <xsl:value-of select="name()"/>
</xsl:message>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
将生成以下输出:
WARNING: Unmatched element: linkGrp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
</head>
<body>
<ul><li>AAAAA<br>DDDDD</li></ul>
<ul><li>BBBBB<br>FFFFF<br>DDDDD<br>EEEEE</li></ul>
<ul><li>CCCCC<br>EEEEE<br>FFFFF</li></ul>
</body>
</html>
另一种解决方案可能是使用xpath函数id()
。但要使其工作,您的XML需要具有DTD DOCTYPE。
像这样:
<!DOCTYPE DIV [
<!ATTLIST s
id ID #REQUIRED
>
]>
<DIV>
<div id="e">
<s id="e1">AAAAA</s>
<s id="e2">BBBBB</s>
<s id="e3">CCCCC</s>
</div>
<div id="fr">
<s id="fr1">DDDDD</s>
<s id="fr2">EEEEE</s>
<s id="fr3">FFFFF</s>
</div>
<linkGrp type="alignment" domains="e fr">
<link target="#e1 #fr1"/>
<link target="#e2 #fr3 #fr1 #fr2"/>
<link target="#e3 #fr2 #fr3"/>
</linkGrp>
</DIV>
使用此XML,您的链接模板可能会更改如下:
<xsl:template match="link">
<ul>
<li>
<xsl:for-each select="id(translate(@target,'#', ''))">
<xsl:if test="position() > 1">
<br/>
</xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
</li>
</ul>
</xsl:template>