使用XSLT从XML中的段落内容创建id(唯一标识符)

时间:2016-12-23 06:34:40

标签: xml xslt

我想创建一个标识符的xsl,将从提供的输入代码中的StatementCode标记部分中提取

输入XML是:

<?xml version="1.0" encoding="UTF-8"?>
<LearningStandards>
    <StatementCodes>
        <StatementCode>AA.BBB-LA.K2.L.1</StatementCode>
    </StatementCodes>
    <Statements>
        <Statement>Demonstrate command of the conventions.</Statement>
    </Statements>
    <StatementCodes>
        <StatementCode>AADD.EPF-Caree.CSDA.L.4</StatementCode>
    </StatementCodes>
    <Statements>
        <Statement>Determine or clarify.</Statement>
    </Statements>
</LearningStandards>

使用的XSLT是:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="LearningStandards">
        <topic id="x1" xml:lang="en-US" outputclass="CCSSI-DITA"><title/>
            <body>
                <xsl:apply-templates/>
            </body>
        </topic>
    </xsl:template>

    <xsl:template match="StatementCodes">
        <bodydiv outputclass="StatementCodes">
            <xsl:apply-templates/>
        </bodydiv>
    </xsl:template>

    <xsl:template match="StatementCode">
        <p outputclass="StatementCode">
            <xsl:apply-templates/>
        </p>
    </xsl:template>

    <xsl:template match="Statements">
        <bodydiv outputclass="Statements">
            <xsl:apply-templates/>
        </bodydiv>
    </xsl:template>

    <xsl:template match="Statement">
        <p outputclass="Statement">
            <xsl:apply-templates/>
        </p>
    </xsl:template>
</xsl:stylesheet>

输出XML是:

<?xml version="1.0" encoding="UTF-8"?>
<topic id="x1" xml:lang="en-US" outputclass="DITA">
    <title/>
    <body>
        <bodydiv outputclass="StatementCodes">
            <p outputclass="StatementCode">AA.BBB-LA.K2.**L.1**</p>
        </bodydiv>
        <bodydiv outputclass="Statements">
            <p outputclass="Statement">Demonstrate command of the conventions.</p>
        </bodydiv>
        <bodydiv outputclass="StatementCodes">
            <p outputclass="StatementCode">AADD.EPF-Caree.CSDA.L.4</p>
        </bodydiv>
        <bodydiv outputclass="Statements">
            <p outputclass="Statement">Determine or clarify.</p>
        </bodydiv>
    </body>
</topic>

我需要输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<topic id="x1" xml:lang="en-US" outputclass="DITA">
    <title/>
    <body>
        <bodydiv outputclass="StatementCodes">
            <p outputclass="StatementCode">AA.BBB-LA.K2.**L.1**</p>
        </bodydiv>
        <bodydiv outputclass="Statements">
            <p id="L.1" outputclass="Statement">Demonstrate command of the conventions.</p>    <!-- id="L.1" is the critical point -->
        </bodydiv>
        <bodydiv outputclass="StatementCodes">
            <p outputclass="StatementCode">AADD.EPF-Caree.CSDA.L.4</p>
        </bodydiv>
        <bodydiv outputclass="Statements">
            <p id="L.4" outputclass="Statement">Determine or clarify.</p>
        </bodydiv>
    </body>
</body>
</topic>

请给我关于这个XSLT的建议。

1 个答案:

答案 0 :(得分:2)

对于给定的Statement元素,要获得相关的“StatementCode”,您似乎需要这样做...

<xsl:variable name="code" select="../preceding-sibling::StatementCodes[1]/StatementCode" />

要在ID中使用此功能,您可以使用Attribute Value Templates

<p outputclass="Statement" id="{$code}">

不幸的是,您失败了解了为什么您只从代码中获得特定子字符串的逻辑。也许你只想获得“L”的部分。向前?如果是这样,表达式将是:

<p outputclass="Statement" id="L.{substring-after($code, '.L.')}">

或者,也许你想要在第三次完整停止之后的所有事情。当您使用XSLT 2.0时,您可以这样做:

<p id="{replace($code, '^\w+\.\w+-\w+\.\w+\.', '')}">

此外,在XSLT 2.0中,如果您希望在倒数第二次完全停止后获取所有内容,则可以使用tokenize(与string-join一起重新加入令牌 - 他们之间的停车)

<p id="{string-join(tokenize($code, '\.')[position() >= last() - 1], '.')}">

试试这个模板,它显示了所有四种方法

 <xsl:template match="Statement">
    <xsl:variable name="code" select="../preceding-sibling::StatementCodes[1]/StatementCode" />
    <p outputclass="Statement" 
          id="{$code}" 
          id1="L.{substring-after($code, '.L.')}" 
          id2="{replace($code, '^\w+\.\w+-\w+\.\w+\.', '')}"
          id3="{string-join(tokenize($code, '\.')[position() >= last() - 1], '.')}">
       <xsl:apply-templates/>
    </p>
 </xsl:template>