#xml #xslt
#xml — файл #в XSLT #xml #xslt
Вопрос:
У меня есть это xml
:
<ns4:Dmpp ProductId="oLRbYoE VfG=" deliveryEnvironment="P" code="1482223" codeType="CNK">
<ns4:Data from="2020-03-01">
<Reimbursable>false</Reimbursable>
</ns4:Data>
<ns4:Data from="2012-06-01" to="2016-07-14">
<Price>6.3100</Price>
<Reimbursable>false</Reimbursable>
</ns4:Data>
<ns4:Data from="2016-07-15" to="2019-12-11">
<Reimbursable>false</Reimbursable>
</ns4:Data>
<ns4:Data from="2019-12-12" to="2020-02-29">
<Price>7.5000</Price>
<Reimbursable>true</Reimbursable>
</ns4:Data>
</ns4:Dmpp>
С помощью этого xsl
<xsl:for-each select="ns4:Dmpp">
<xsl:text>INSERT INTO DMPPACKAGING VALUES ('</xsl:text>
<xsl:value-of select="@ProductId" />
<xsl:text>','</xsl:text>
<xsl:value-of select="@deliveryEnvironment" />
<xsl:text>','</xsl:text>
<xsl:for-each select="ns4:Data">
<xsl:sort select="translate(@from,'-','')" order="descending" data-type="number" />
<xsl:if test="position() = 1">
<xsl:value-of select="@from" />
<xsl:text>','</xsl:text>
<xsl:choose>
<xsl:when test="@to !=''">
<xsl:value-of select="@to"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'0000-00-00'" />
</xsl:otherwise>
</xsl:choose>
<xsl:text>','</xsl:text>
<xsl:value-of select="../@codeType" />
<xsl:text>','</xsl:text>
<xsl:value-of select="../@code" />
<xsl:text>','</xsl:text>
<xsl:value-of select="Reimbursable" />
<xsl:text>','</xsl:text>
<xsl:choose>
<xsl:when test="Price !=''">
<xsl:value-of select="Price"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="../ns4:Data/following-sibling::ns4:Data/Price" />
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:for-each>
<xsl:text>');</xsl:text>
</xsl:for-each>
Как вы можете видеть в этом примере, Position() = 1
дайте мне только данные <Reimbursable>
элемента.
Я хотел бы получить более свежую информацию о цене продукта. С моим кодом я получаю его, только если это второй элемент отсортированного элемента, но это не всегда так.
Любая помощь будет оценена по достоинству !
Комментарии:
1. Если вам нужна самая последняя цена, то сортируйте только те узлы, у которых есть цена.
2. Не уверен, что я действительно понимаю, что вы хотите, но если вам нужна последняя цена, вы могли бы изменить свое последнее значение выбора на <xsl:значение выбора=»../ns4:Данные / следующие-sibling::ns4:Data[position()=last()]/Price»/>
3. @michael.hor257k Мне нужны данные из самого последнего
Reimbursable
элемента и данные из самого последнегоPrice
элемента. ИногдаReimbursable
иPrice
находятся в одном и том жеns4:Data
элементе, но иногда нет. Итак, в этом примере мне нужно<Reimbursable>false</Reimbursable>
из<ns4:Data from="2020-03-01">
и<Price>7.5000</Price>
из<ns4:Data from="2019-12-12" to="2020-02-29">
4. Тогда я предлагаю вам сначала отсортировать узлы, у которых есть
Reimbursable
элемент, и получить первый из них, затем отсортировать узлы, у которых естьPrice
элемент, и получить первый из них. В противном случае вам пришлось бы поместить отсортированные узлы в переменную, преобразовать переменную в набор узлов (предполагая XSLT 1.0), а затем искать первый узел, у которого естьReimbursable
элемент, и — отдельно — первый узел, у которого естьPrice
элемент. Намного сложнее.
Ответ №1:
На самом деле, мое предложение состояло в том, чтобы сделать:
<xsl:text>MOST RECENT REIMBURSABLE: </xsl:text>
<xsl:for-each select="ns4:Data[Reimbursable]">
<xsl:sort select="@from" order="descending" />
<xsl:if test="position() = 1">
<xsl:value-of select="@from"/>
</xsl:if>
</xsl:for-each>
<xsl:text> MOST RECENT PRICE: </xsl:text>
<xsl:for-each select="ns4:Data[Price]">
<xsl:sort select="@from" order="descending" />
<xsl:if test="position() = 1">
<xsl:value-of select="@from"/>
</xsl:if>
</xsl:for-each>
Ответ №2:
Вот как я решил свою проблему с помощью предложения @michael.hor257k :
Я только помещу код внутрь, <xsl:choose>
где мне нужно получить более свежий Price
элемент.
<xsl:choose>
<xsl:when test="Price !=''">
<xsl:value-of select="Price"/>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="../ns4:Data/Price">
<xsl:sort select="translate(../@from,'-','')" order="descending" data-type="number" />
<xsl:if test="position() = 1">
<xsl:value-of select="." />
</xsl:if>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>