#xml #xslt #xslt-2.0 #xslt-1.0
#xml #xslt #xslt-2.0 #xslt-1.0
Вопрос:
Я новичок в XSLT в целом, поэтому, пожалуйста, потерпите меня…
Имея это в виду, то, что я пытаюсь сделать, это проверить наличие определенного тега в XML. Если он есть, я хочу применить шаблон. Если нет, я хочу добавить его (как пустое значение). В основном всегда заставляя его быть в конечном выводе. Как бы мне это сделать?
У меня было что-то вроде этого…
<xsl:choose>
<xsl:when test="@href">
<xsl:apply-templates select="country" />
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
Верхняя часть кода — это то, что я считаю неправильным. Нужно что-то в otherwise
теге, и я думаю, что моя when
часть неверна.
<xsl:template match="country">
<xsl:if test=". != '' or count(./@*) != 0">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
Кто-нибудь может помочь? Заранее благодарю вас.
Редактировать:
Да, в конце концов, мне нужен, по крайней мере, <country />
тег, который должен быть в XML. Но возможно, что он не существует вообще. Если он не существует, я должен его вставить. Примером хорошего ввода было бы <country>US</country>
Комментарии:
1. Рассмотрите возможность публикации двух входных образцов (один с присутствующими данными, другой с отсутствующими данными), затем покажите нам выходные данные, которые вы хотите создать для обоих. Тогда мы можем помочь с правильным XSLT. Боюсь, ваше текущее описание «проверка на наличие определенного тега» не очень точное, и трудно сказать,
<xsl:when test="@href">
соответствует ли оно вашим требованиям. Это проверит, имеет ли контекстный узелhref
атрибут, тогда как проверка на наличие «тега» звучит так, что вы хотите проверить определенный элемент node. В вашемotherwise
вы просто можете захотеть поместить<country>foo</country>
результат el2. ‘<xsl:when test=»@href»>’, я полагаю, неверно
3. Хороший вопрос, 1. Смотрите мой ответ для еще более короткого и простого решения, чем принятое в настоящее время. В моем решении абсолютно отсутствуют условные инструкции XSLT!
Ответ №1:
В шаблоне для родительского элемента ожидается, что элемент country будет использоваться, например
<xsl:template match="foo">
<xsl:if test="not(country)">
<country>US</country>
</xsl:if>
<xsl:apply-templates/>
</xsl:template>
Вместо foo
используйте имя родительского элемента. И, конечно, вы могли бы также выполнить другие действия, такие как копирование элемента, я сосредоточился на if
проверке. На самом деле вам не нужно, xsl:choose/when/otherwise
на мой взгляд, xsl:if
должно быть достаточно, поскольку apply-templates ничего не будут делать с дочерними элементами, которые не существуют.
Комментарии:
1. я сделал кое-что очень similar….so я думаю, вы получили правильный ответ. для этого было важно время, поэтому я использовал его, пока оно не было правильным. но спасибо в любом случае.
2. Что, если бы я хотел посмотреть, не существует ли он, или пустой, если он существует?
3. @SearchForKnowledge, подумайте о том, чтобы задать новый отдельный вопрос с необходимыми деталями ввода XML и желаемого результата.
Ответ №2:
Еще проще:
<xsl:template match="foo[not(country)]">
<country>US</country>
<xsl:apply-templates/>
</xsl:template>
Обратите внимание:
Никакие условные инструкции XSLT (такие как <xsl:if>
) не используются и в них нет необходимости.
Очень часто наличие <xsl:if>
или <xsl:choose>
указывает на то, что код можно переработать и значительно улучшить, среди прочего, избавившись от условных инструкций.
Комментарии:
1. Но что бы вы сделали, если бы вам понадобилось предоставить другой элемент по умолчанию? например, <город>.
2. @JRQ, в данном конкретном случае не предоставлен конкретный исходный XML-документ, поэтому можно только догадываться о желаемой схеме. Скажите: ` <страна> США</country> <город> Вашингтон</city> ` Или, это может быть (возможности бесконечны): ` <название страны=»US»> <город> Вашингтон</city> </country> `
3. Я это вижу. Но более общее решение было бы лучше, чем то, которое больше не работает, когда количество тестов больше одного.
4. @JRQ, согласен. Вот почему любой может задать новый вопрос с более конкретным сценарием, который его интересует.
Ответ №3:
Вам даже не нужна какая-либо условная обработка. Эта таблица стилей:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item[not(country)]">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<country>Lilliput</country>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
С помощью этого ввода:
<root>
<item>
<country>Brobdingnag</country>
</item>
<item>
<test/>
</item>
</root>
Вывод:
<root>
<item>
<country>Brobdingnag</country>
</item>
<item>
<test></test>
<country>Lilliput</country>
</item>
</root>