1

我的 XML 源在linkGrp. 基于@target 属性指定的那些交叉引用,我需要对s元素的值进行分组。如果目标属性包含一对一的引用,我的代码如下:

<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>

但是,当我为元素中的一个 @target 添加更多交叉引用时,我的 XSLT 代码无法正常工作,link如下所示:

<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 代码中的错误或提供替代解决方案?

4

1 回答 1

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>
于 2013-07-10T21:02:29.003 回答