Если вы хотите использовать несколько зерен, тип tgt_ compound
не grains
.
См .: https://docs.saltstack.com/en/latest/ref/clients/#salt-s-client-interfaces , https://docs.saltstack.com. /en/latest/topics/targeting/compound.html
Вы пытаетесь соответствовать xml элементам именам "Level1", "Level2", и т.д...., которые не существуют в документе. Затем Вы ищете атрибут 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, пока каждое значение в соответствующем элементе Даты не пусто.
То, что это делает,
*
соответствия все дети. [.='']
означает, "пусто". Наконец, это переносит все это в нет. Это означает, если только передает, если нет никакого ребенка, который пуст.Можно также хотеть проверить учебные руководства XPath и W3Schools XSL.
Вы не определили хорошо что означает то, чтобы "узел имел значение".
По всей вероятности Вы рассмотрите элемент, который имеет белого текстового ребенка только для пространства, чтобы не иметь значение. В этом случае, ниже одно решение:
<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>
Этот templete для элемента "Даты" не будет подобран, если "Дата" содержала даже один дочерний элемент, который не имеет никакого довольного или только пробел.
Когда это преобразование применяется на следующий 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>
Избыточно - это относится к атрибутам XML.
Вы пытаетесь протестировать на элемент, поэтому просто отбрасывают.
Кроме того:
<xsl:for-each select="Level1/Level2/Level3">
<MyDates>
<xsl:if test="VALUE1!=''">
<value_1>
<xsl:value-of select="VALUE1"/>
</value_1>
</xsl:if>
<xsl:if test="VALUE2!=''">
<value_2>
<xsl:value-of select="VALUE2"/>
</value_2>
</xsl:if>
<xsl:if test="VALUE3!=''">
<value_3>
<xsl:value-of select="VALUE3"/>
</value_3>
</xsl:if>
<xsl:if test="VALUE4!=''">
<value_4>
<xsl:value-of select="VALUE4"/>
</value_4>
</xsl:if>
</MyDates>
Я думаю, вы можете сделать и это. Вместо проверки узла. VALUE1/text() будет проверять, есть ли в узле текст. Возможно, вы захотите убедиться, что в них нет белого пространства. Также можно проверить, есть ли у элемента VALUE1 дочерний узел.
<xsl:if test="VALUE1/text()">
</xsl:if>
<xsl:if test="VALUE1/child::node()">
</xsl:if>