使用xsl:number并将当前元素属性的子字符串与前一个兄弟属性子字符串的第一个实例匹配?

时间:2013-08-27 19:35:54

标签: xml regex xslt-2.0

如何使用xsl:number将当前元素属性的子字符串与前一个兄弟属性的子字符串的第一个实例匹配?

如果查看下面的Source XML文件,当bookDocument的pages属性的子字符串(字符1 - 5)在另外的bookDocuments中重复时,我打算在输出文件中插入一个字母值(以“a”开头)每个后续bookDocument的doc_code属性,其pages属性substring 1-5与第一个匹配。我一直试图使用xsl:number来实现所需的结果,但是使用xsl:number的“from”和“count”功能都没有成功。请参阅结果文件resultdoc_5_12351.xml的doc_code属性作为错误输出的示例。我非常感谢你对我做错了什么有用的建议。

源XML文件:

<book>
<bookGlossary>
<para>Here is a glossary.</para>
</bookGlossary>
<bookPart>
<bookChapter>
<title>Chapter 1</title>        

<bookDocument docnum='1' pages="12345,12346">
<para>This is the newDoc that should output a doc_code of 12345</para>              
</bookDocument>

<bookDocument docnum='2' pages="12346,12347,12348,12349,12350">
<para>This is the newDoc that should output a doc_code of 12346</para>              
</bookDocument>     

<bookDocument docnum='3' pages="12350,12351">
<para>This is the newDoc that should output a doc_code of 12350</para>              
</bookDocument>     

<bookDocument docnum='4' pages="12351">
<para>This is the newDoc that should output a doc_code of 12351</para>              
</bookDocument>     

<bookDocument docnum='5' pages="12351">
<para>This is the newDoc that should output a doc_code of 12351a</para>
</bookDocument>     

<bookDocument docnum='6' pages="12351,12352">
<para>This is the newDoc that should output a doc_code of 12351b</para>         
</bookDocument>

<bookDocument docnum='7' pages="12353">
<para>This is the newDoc that should output a doc_code of 12353</para>          
</bookDocument>

<bookDocument docnum='8' pages="12353">
<para>This is the newDoc that should output a doc_code of 12353a</para>         
</bookDocument> 

<bookDocument docnum='9' pages="12354">
<para>This is the newDoc that should output a doc_code of 12354</para>          
</bookDocument>

<bookDocument docnum='10' pages="12354, 12355">
<para>This is the newDoc that should output a doc_code of 12354a</para>         
</bookDocument> 

<bookDocument docnum='11' pages="12355">
<para>This is the newDoc that should output a doc_code of 12355</para>          
</bookDocument>

<bookDocument docnum='12' pages="12355">
<para>This is the newDoc that should output a doc_code of 12355a</para>         
</bookDocument>

<bookDocument docnum='13' pages="12356">
<para>This is the newDoc that should output a doc_code of 12356</para>          
</bookDocument>

</bookChapter>
</bookPart>
</book>

我目前的XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" omit-xml-declaration="yes" indent="yes" encoding="UTF-8"/>

<xsl:template match="/book">

<xsl:for-each select="bookPart/bookChapter/bookDocument">
<xsl:result-document href="resultdoc_{@docnum}_{@pages/substring(., 1, 5)}.xml">
<newDoc>
<docStart>

<xsl:attribute name="doc_code">
<xsl:choose>
<xsl:when test="preceding-sibling::bookDocument/@pages/substring(., 1, 5) = current()/@pages/substring(., 1, 5)">
<xsl:value-of select="@pages/substring(., 1, 5)"/>
<xsl:number level="any" from="bookDocument[preceding-sibling::bookDocument[@pages/substring(., 1, 5) = current()/@pages/substring(., 1, 5)]]" format="a"/></xsl:when>
<xsl:otherwise><xsl:value-of select="@pages/substring(., 1, 5) "/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>


</docStart>
<docBody>
<xsl:apply-templates select="*|text()"/>
</docBody>
</newDoc>
</xsl:result-document>
</xsl:for-each>
</xsl:template>

<xsl:template match="*|@*|text()">
<xsl:copy>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="text()">
<xsl:if test="normalize-space(.)">
<xsl:value-of select="normalize-space(.)"/>
</xsl:if>
<xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

结果文档的doc_code属性值不正确:

<!--resultdoc_1_12345.xml-->

<newDoc>
<docStart doc_code="12345"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12345</para>
</docBody>
</newDoc>

<!--resultdoc_2_12346.xml-->


<newDoc>
<docStart doc_code="12346"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12346</para>
</docBody>
</newDoc>

<!--resultdoc_3_12350.xml-->


<newDoc>
<docStart doc_code="12350"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12350</para>
</docBody>
</newDoc>


<!--resultdoc_4_12351.xml-->


<newDoc>
<docStart doc_code="12351"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12351</para>
</docBody>
</newDoc>

<!--resultdoc_5_12351.xml-->


<newDoc>
<docStart doc_code="12351e"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12351a</para>
</docBody>
</newDoc>

<!--resultdoc_6_12351.xml-->


<newDoc>
<docStart doc_code="12351b"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12351b</para>
</docBody>
</newDoc>


<!--resultdoc_7_12353.xml-->


<newDoc>
<docStart doc_code="12353"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12353</para>
</docBody>
</newDoc>

<!--resultdoc_8_12353.xml-->


<newDoc>
<docStart doc_code="12353c"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12353a</para>
</docBody>
</newDoc>

<!--resultdoc_9_12354.xml-->


<newDoc>
<docStart doc_code="12354"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12354</para>
</docBody>
</newDoc>

<!--resultdoc_10_12354.xml-->


<newDoc>
<docStart doc_code="12354c"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12354a</para>
</docBody>
</newDoc>

<!--resultdoc_11_12355.xml-->


<newDoc>
<docStart doc_code="12355"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12355</para>
</docBody>
</newDoc>

<!--resultdoc_12_12355.xml-->


<newDoc>
<docStart doc_code="12355c"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12355a</para>
</docBody>
</newDoc>

<!--resultdoc_13_12356.xml-->


<newDoc>
<docStart doc_code="12356"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12356</para>
</docBody>
</newDoc>

1 个答案:

答案 0 :(得分:0)

我的第一印象是:

(a)这可能超出了xsl:number

的能力

(b)你的xsl:number模式不起作用的原因是在模式中,current()指的是与模式匹配的节点,而我认为你的代码假设它与被编号的节点匹配

我会将此作为分组问题解决(使用<xsl:for-each-group group-adjacent= "@pages/substring(., 1, 5)">;您可以使用<xsl:number value="position()" format="a">来获取和格式化表示其组内bookDocument位置的数字。