Сообщение об ошибке при попытке сгруппировать элементы в xsl
Я пытаюсь сгруппировать каждые два элемента tei:div следующего xml (который является частью большего файла, содержащего мое резюме) и обернуть их в <div type="reference_block">
:
<div type="category">
<head n="references">References</head>
<div type="reference" xml:id="1">
<persName>
<forename type="first">firstname1</forename>
<surname>surname1</surname>
</persName>
<address>
<name type="building">building1</name>
<postBox>postbox1</postBox>
<placeName>
<settlement>settlement1</settlement>
<region>region1</region>
<country>country1</country>
</placeName>
<postCode>postcode1</postCode>
</address>
<num n="telephone">telephone1</num>
<email>email1</email>
</div>
<div type="reference" xml:id="2">
<persName>
<forename type="first">firstname2</forename>
<surname>surname2</surname>
</persName>
<address>
<name type="building">building2</name>
<postBox>postbox2</postBox>
<placeName>
<settlement>settlement2</settlement>
<region>region2</region>
<country>country2</country>
</placeName>
<postCode>postcode2</postCode>
</address>
<num n="telephone">telephone2</num>
<email>email2</email>
</div>
<div type="reference" xml:id="3">
<persName>
<forename type="first">firstname3</forename>
<surname>surname3</surname>
</persName>
<address>
<name type="building">building3</name>
<postBox>postbox3</postBox>
<placeName>
<settlement>settlement3</settlement>
<region>region3</region>
<country>country3</country>
</placeName>
<postCode>postcode3</postCode>
</address>
<num n="telephone">telephone3</num>
<email>email3</email>
</div>
<div type="reference" xml:id="4">
<persName>
<forename type="first">firstname4</forename>
<surname>surname4</surname>
</persName>
<address>
<name type="building">building4</name>
<postBox>postbox4</postBox>
<placeName>
<settlement>settlement4</settlement>
<region>region4</region>
<country>country4</country>
</placeName>
<postCode>postcode4</postCode>
</address>
<num n="telephone">telephone4</num>
<email>email4</email>
</div>
<div type="reference" xml:id="5">
<persName>
<forename type="first">firstname5</forename>
<surname>surname5</surname>
</persName>
<address>
<name type="building">building5</name>
<postBox>postbox5</postBox>
<placeName>
<settlement>settlement5</settlement>
<region>region5</region>
<country>country5</country>
</placeName>
<postCode>postcode5</postCode>
</address>
<num n="telephone">telephone5</num>
<email>email5</email>
</div>
<div type="reference" xml:id="6">
<persName>
<forename type="first">firstname6</forename>
<surname>surname6</surname>
</persName>
<address>
<name type="building">building6</name>
<postBox>postbox6</postBox>
<placeName>
<settlement>settlement6</settlement>
<region>region6</region>
<country>country6</country>
</placeName>
<postCode>postcode6</postCode>
</address>
<num n="telephone">telephone6</num>
<email>email6</email>
</div>
<div type="reference" xml:id="7">
<persName>
<forename type="first">firstname7</forename>
<surname>surname7</surname>
</persName>
<address>
<name type="building">building7</name>
<postBox>postbox7</postBox>
<placeName>
<settlement>settlement7</settlement>
<region>region7</region>
<country>country7</country>
</placeName>
<postCode>postcode7</postCode>
</address>
<num n="telephone">telephone7</num>
<email>email7</email>
</div>
</div>
Я использую этот шаблон, чтобы попытаться обернуть элементы:
<xsl:template match="tei:div[@type='reference']">
<xsl:if test="@xml:id mod 2 = 1">
<div class="reference_block">
<xsl:apply-templates select=".|following-sibling::tei:div[@type='reference'][@xml:id < 2]"/>
</div>
</xsl:if>
</xsl:template>
Однако, когда я делаю это, я получаю сообщение об ошибке: "Слишком много вложенных вызовов apply-templates. Возможно, таблица стилей зацикливается"
Проблема, кажется, в "." в моем выборе, но я не уверен, почему я получаю сообщение об ошибке. Может быть, это потому, что он звонит сам, а я этого не понимаю? Может ли кто-нибудь дать мне некоторое представление о том, почему это может происходить, или об альтернативном способе группировки элементов, для которых не требуется "." Выбрать? Спасибо!
1 ответ
"."
действительно вызывает проблему, так как он представляет текущий контекстный узел (т. е. узел div, который вы в данный момент сопоставили), и поэтому его выбор просто вызовет сопоставление того же шаблона, а внутри шаблона test="@xml:id mod 2 = 1"
все еще будет правдой, что приведет к бесконечной рекурсии.
Если вы просто хотите скопировать текущий div и следующий div, просто замените xsl: apply-templates на xsl: copy-of. Обратите внимание, ваше выражение для получения следующего брата тоже не совсем верно. Вы хотите сравнить идентификатор следующего элемента с идентификатором текущего элемента
Попробуй это...
<xsl:copy-of select=".|following-sibling::tei:div[@type='reference'][@xml:id < current()/@xml:id + 2]"/>
Или, если идентификаторы всегда будут в порядке, это будет работать тоже
<xsl:copy-of select=".|following-sibling::tei:div[@type='reference'][1]"/>
С другой стороны, если вы хотите выполнить дополнительное преобразование для пары выбранных вами элементов div, вы можете использовать атрибут mode, чтобы другой шаблон соответствовал
<xsl:template match="tei:div[@type='reference']">
<xsl:if test="@xml:id mod 2 = 1">
<div class="reference_block">
<xsl:apply-templates select=".|following-sibling::tei:div[@type='reference'][1]" mode="group"/>
</div>
</xsl:if>
</xsl:template>
<xsl:template match="tei:div" mode="group">
<!-- Other code here -->
</xsl:template>