Привет,
Есть вопрос по трансформациям. А точнее даже по XPath выражениям. (Используется MSXML парсер).
Если кратко, то немогу найти способ записать следующее, но без временной переменной (для использования в selectSingleNode):
<xsl:variable name="temp_parentid" select="@parentid" />
parent's code: [<xsl:value-of select="../car[@id=$temp_parentid]/@code" />],
Другими словами нужно найти вершину в другом месте дерева, указав в условии значение(я) из текущей вершины. Т.е. хотелось бы что-то типа:
node = currentNode.selectSingleNode("../car[@id=self::@parentid]/@code");
или
node = currentNode.selectSingleNode("../car[@id=self::node()/@parentid]/@code");
Оба варианта делают не совсем то, что нужно — синтаксическая ошибка либо self::node() ссылается уже на ../car а не на текущую вершину currentNode.
Есть еще вариант:
node = currentNode.selectSingleNode("../car[@id=current()/@parentid]/@code");
Но функция current() доступна только из XSLT трансформаций.
Более подробно, XML, XSLT и результат (там есть закоментированный choose, где собственно и варианты):
XML:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="refchoose.xsl" ?>
<cars>
<car id="1" parentid="" type="light" color="red" code="xx001" />
<car id="2" parentid="" type="medium" color="green" code="xx002"/>
<car id="3" parentid="2" type="heavy" color="yellow" code="xx003"/>
<car id="4" parentid="2" type="light" color="blue" code="xx004"/>
<car id="8" parentid="8" type="heavy" color="black" code="xx005"/>
<car id="5" parentid="3" type="light" color="green" code="xx006"/>
<car id="6" parentid="5" type="medium" color="red" code="xx007"/>
<car id="7" parentid="5" type="heavy" color="black" code="xx008"/>
</cars>
XSL:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="/cars">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="car">
<span>
car, @id [<xsl:value-of select="@id"/>],
<xsl:variable name="temp_parentid" select="@parentid" />
parent's code: [<xsl:value-of select="../car[@id=$temp_parentid]/@code" />],
is parent's color green?
<xsl:choose>
<xsl:when test="../car[@id=$temp_parentid and @color='green']">YES</xsl:when>
<xsl:otherwise>no</xsl:otherwise>
</xsl:choose>
<!--
//вот например переписать этот choose, но уже без временной переменной
Color of parent is green?
<xsl:choose>
<xsl:when test="../car[@id=self::@parentid and @color='green']">YES</xsl:when>
<xsl:when test="../car[@id=self::node()/@parentid and @color='green']">YES</xsl:when>
<xsl:otherwise>no</xsl:otherwise>
</xsl:choose>
-->
</span>
<BR/>
</xsl:template>
</xsl:stylesheet>
Результат:
car, @id [1], parent's code: [], is parent's color green? no
car, @id [2], parent's code: [], is parent's color green? no
car, @id [3], parent's code: [xx002], is parent's color green? YES
car, @id [4], parent's code: [xx002], is parent's color green? YES
car, @id [8], parent's code: [xx005], is parent's color green? no
car, @id [5], parent's code: [xx003], is parent's color green? no
car, @id [6], parent's code: [xx006], is parent's color green? YES
car, @id [7], parent's code: [xx006], is parent's color green? YES
Последняя идея, это реализовать предпарсер XPath выражений, и все что в {..} заменять на значения. В итоге например в "../car[@id={@parentid}]/@code", {@parentid} будет заменено на значение @parentid и запрос превратиться в:
node = currentNode.selectSingleNode("../car[@id="5"]/@code");
Но уж очень не хочется писать пред-парсер селектов
Спасибо!
Здравствуйте, Fors77, Вы писали:
F>Привет,
F>Есть вопрос по трансформациям. А точнее даже по XPath выражениям. (Используется MSXML парсер).
F>Если кратко, то немогу найти способ записать следующее, но без временной переменной (для использования в selectSingleNode):
F><xsl:variable name="temp_parentid" select="@parentid" />
F>parent's code: [<xsl:value-of select="../car[@id=$temp_parentid]/@code" />],
F>Последняя идея, это реализовать предпарсер XPath выражений, и все что в {..} заменять на значения. В итоге например в "../car[@id={@parentid}]/@code", {@parentid} будет заменено на значение @parentid и запрос превратиться в:
F>node = currentNode.selectSingleNode("../car[@id="5"]/@code");
F>Но уж очень не хочется писать пред-парсер селектов
По всей видимости придется писать предпарсер, зато и работать быстрее будет, чем если реализовать
какой-нить способ (а я сомневаюсь, что это возможно) чисто через Xpath