У меня есть XML-сборка
<elig>
<subscriber code = "1234"/>
<date to = "12/30/2004"
from = "12/31/2004"/>
<person name = "bob"
ID = "654321"/>
<dog type = "labrador"
color = "white"/>
<location name = "hawaii"
islandCode = "01"/>
</subscriber>
</elig>
В XSL у меня есть:
<xsl:template match = "subscriber">
<xsl:for-each select = "date">
<xsl:apply-templates match = "person" />
<xsl:apply-templates match = "location" />
<xsl:apply-templates match = "dog" />
</xsl:for-each>
</xsl:template>
У меня проблема в том, что мне нужен блок местоположения между человеком и блоком собаки. Я пробовал ../, и это не работает. Я сильно упростил это, но суть понятна. Кажется, я не могу вспомнить, что мне нужно поставить перед местом, чтобы заставить его работать. Спасибо.





Я изменил одну опечатку в вашем примере XML:
<elig>
<subscriber code = "1234">
<date to = "12/30/2004" from = "12/31/2004"/>
<person name = "bob" ID = "654321"/>
<dog type = "labrador" color = "white"/>
<location name = "hawaii" islandCode = "01"/>
</subscriber>
</elig>
И с этой таблицей стилей все работает нормально:
<xsl:template match = "subscriber">
<xsl:for-each select = "date">
<xsl:apply-templates select = "../person" />
<xsl:apply-templates select = "../location" />
<xsl:apply-templates select = "../dog" />
</xsl:for-each>
</xsl:template>
<xsl:template match = "person">person</xsl:template>
<xsl:template match = "location">location</xsl:template>
<xsl:template match = "dog">dog</xsl:template>
Выход:
personlocationdog
Прежде всего, ваш XML все еще не сформирован правильно, и я действительно не могу понять, почему вы перебираете теги <date/> - внутри <date/> есть только один тег <subscriber/> (при условии, что первый <subscriber/> не должен самозакрываться).
При использовании XPath вы всегда должны думать о контексте, в котором вызывается XPatch. Следующее должно сделать это (когда мое предположение о вашей структуре данных верно):
<xsl:template match = "subscriber">
<xsl:for-each select = "date">
<!-- from here on we're in the context of the date-tag -->
<xsl:apply-templates match = "../person" />
<xsl:apply-templates match = "../location" />
<xsl:apply-templates match = "../dog" />
</xsl:for-each>
</xsl:template>
У меня была куча ошибок, и однажды я исправил ../ расположение сработало, как раз в один из тех дней .....
В этом случае не логичнее вынести вызовы apply-template за пределы цикла for-each? Поскольку элементы person, location и dog являются дочерними по отношению к подписчику, они должны обрабатываться в рамках подписчика, а не в рамках даты.
То есть:
<xsl:template match = "subscriber">
<xsl:for-each select = "date">
<!-- Perform the processing of the date tags here-->
</xsl:for-each>
<xsl:apply-templates match = "person" />
<xsl:apply-templates match = "location" />
<xsl:apply-templates match = "dog" />
</xsl:template>
<xsl:template match = "subscriber">
<xsl:apply-templates match = "date" />
</xsl:template>
<xsl:template match = "date">
<xsl:apply-templates match = "../person" />
<xsl:apply-templates match = "../location" />
<xsl:apply-templates match = "../dog" />
</xsl:template>
instead of xsl:for-each on date better practice is having a template match for date.
Следует иметь в виду, что
xsl:for-eachизменяет узел контекста внутри элемента for-each на текущий узел в наборе узлов, выбранном для каждого элемента. Вот почему вам нужна родительская ось (../).