Мне нужна помощь с синтаксисом XSLT. Вот мой сценарий, у меня есть XML-файл, который нужно преобразовать в другой вид XML-файла, у меня есть несколько разделов, где, если конкретный набор узлов не содержит никакого значения, весь раздел не должен обрабатываться.
Вот пример XML:
<Dates>
<Date>
<VALUE1></VALUE1>
<VALUE2></VALUE2>
<VALUE3></VALUE3>
<VALUE4></VALUE4>
<VALUE5>3333</VALUE5>
</Date>
<Date>
<VALUE1>AAAA</VALUE1>
<VALUE2></VALUE2>
<VALUE3>JJJJ</VALUE3>
<VALUE4></VALUE4>
<VALUE5>12345</VALUE5>
</Date>
</Dates>
Вот мой XSLT с оператором if, который не работает правильно
<xsl:for-each select = "Level1/Level2/Level3">
<xsl:if test = "@VALUE1!=''">
<MyDates>
<value_1>
<xsl:value-of select = "VALUE1"/>
</value_1>
<value_2>
<xsl:value-of select = "VALUE2"/>
</value_2>
<value_3>
<xsl:value-of select = "VALUE3"/>
</value_3>
<value_4>
<xsl:value-of select = "VALUE4"/>
</value_4>
</MyDates>
</xsl:if>
</xsl:for-each>
Итак, как вы можете видеть, я в основном хочу, чтобы все узлы (VALUE1, VALUE2, VALUE3 и т. д.) Имели значения или иначе не обрабатывались и переходили к следующему разделу
(Если вы не видите XML, подумал, я также сделал снимок экрана)
Может быть, если включить и образец выход?
@Alex: У вас есть два хороших ответа: Крис Марасти-Георг и Димитр





Вы пытаетесь сопоставить элементы xml с именами «Уровень1», «Уровень2» и т. д., Которых нет в документе. Затем вы ищете атрибут VALUE1 в последнем элементе.
Я считать вы хотите что-то вроде этого:
<xsl:for-each select = "Dates">
<MyDates>
<xsl:for-each select = "Date">
<xsl:if test = "not(*[.=''])">
<MyDate>
<value_1>
<xsl:value-of select = "VALUE1"/>
</value_1>
<value_2>
<xsl:value-of select = "VALUE2"/>
</value_2>
<value_3>
<xsl:value-of select = "VALUE3"/>
</value_3>
<value_4>
<xsl:value-of select = "VALUE4"/>
</value_4>
</MyDate>
</xsl:if>
</xsl:for-each>
</MyDates>
</xsl:for-each>
Это добавит новый элемент MyDate, если значение каждый в соответствующем элементе Date не будет пустым.
Что он делает
* подходит для всех детей. [.=''] означает «пусто». Наконец, он оборачивает все это в not. Это означает, что if проходит, только если нет пустого дочернего элемента.@ Является избыточным - он относится к атрибутам XML.
Вы пытаетесь проверить элемент, поэтому просто отбросьте @.
Кроме того:
Вы не очень хорошо определили, что значит «узел имеет значение».
Скорее всего, вы сочтете, что элемент, имеющий дочерний текст, состоящий только из пробелов, не имеет значения. В этом случае ниже представлено одно решение:
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration = "yes" indent = "yes"/>
<xsl:template match = "Date[not(*[not(normalize-space())])]">
<xsl:copy-of select = "."/>
</xsl:template>
<xsl:template match = "text()"/>
</xsl:stylesheet>
Этот шаблон для элемента «Дата» не будет сопоставлен, если «Дата» содержит хотя бы один дочерний элемент, не имеющий содержимого или только пробел..
Когда это преобразование применяется к следующему XML-документу:
<Dates>
<Date>
<VALUE1></VALUE1>
<VALUE2> </VALUE2>
<VALUE3></VALUE3>
<VALUE4></VALUE4>
<VALUE5>3333</VALUE5>
</Date>
<Date>
<VALUE1>AAAA</VALUE1>
<VALUE2>1</VALUE2>
<VALUE3>JJJJ</VALUE3>
<VALUE4>1</VALUE4>
<VALUE5>12345</VALUE5>
</Date>
</Dates>
Получен правильный результат:
<Date>
<VALUE1>AAAA</VALUE1>
<VALUE2>1</VALUE2>
<VALUE3>JJJJ</VALUE3>
<VALUE4>1</VALUE4>
<VALUE5>12345</VALUE5>
</Date>
Я думаю, ты тоже можешь это сделать. Вместо проверки узла. VALUE1 / text () проверит, есть ли в узле текст. Возможно, вы захотите убедиться, что для них нет пробелов. Также вы можете увидеть, есть ли у элемента VALUE1 дочерний узел.
<xsl:if test = "VALUE1/text()">
</xsl:if>
<xsl:if test = "VALUE1/child::node()">
</xsl:if>
<xsl:template match = "Dates">
<table border = "1">
<tr bgcolor = "#9acd32"><th>NAME</th><th>INVALUE</th></tr>
<xsl:for-each select = "Date">
<xsl:if test = "(VALUE1 != '') and (VALUE2 != '') and (VALUE3 != '') and (VALUE4 != '') and (VALUE5 != '')" >
<tr><td>VALUE1</td><td><xsl:value-of select = "VALUE1"></xsl:value-of></td></tr>
<tr><td>VALUE2</td><td><xsl:value-of select = "VALUE2"></xsl:value-of></td></tr>
<tr><td>VALUE3</td><td><xsl:value-of select = "VALUE3"></xsl:value-of></td></tr>
<tr><td>VALUE4</td><td><xsl:value-of select = "VALUE4"></xsl:value-of></td></tr>
<tr><td>VALUE5</td><td><xsl:value-of select = "VALUE5"></xsl:value-of></td></tr>
</xsl:if>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
Ваш XSLT не прошел.