#xslt
Вопрос:
У меня есть следующий XML:
lt;Documentgt; lt;Rowgt; lt;KEYgt;NIKE|JB|APPAREL|MENSlt;/KEYgt; lt;Periodgt;Nov-21lt;/Periodgt; lt;/Rowgt; lt;Rowgt; lt;KEYgt;FASCINATE|JB|ACCESSORIES|LADIESlt;/KEYgt; lt;Matchesgt; lt;Rowgt; lt;KEYgt;FASCINATE|JB|ACCESSORIES|LADIESlt;/KEYgt; lt;Periodgt;Nov-22lt;/Periodgt; lt;/Rowgt; lt;/Matchesgt; lt;/Rowgt; lt;/Documentgt;
Я хочу использовать XSLT для возврата вложенного /Matches/Row/Period
, когда Document/Row/Period
значение не определено (как во втором Row
XML).
Итак, у меня есть следующий XSLT:
lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://exampleincludednamespace.com/" exclude-result-prefixes="ns"gt; lt;xsl:output method="xml" omit-xml-declaration="yes" /gt; lt;xsl:template match="/"gt; lt;Documentgt; lt;xsl:for-each select="/Document/Row"gt; lt;xsl:variable name="period" select="/Period" /gt; lt;xsl:choosegt; lt;xsl:when test="$period = null"gt; lt;xsl:copygt; lt;xsl:copy-of select="KEY | /Matches/Row/Period" /gt; lt;/xsl:copygt; lt;/xsl:whengt; lt;xsl:otherwisegt; lt;xsl:copygt; lt;xsl:copy-of select="KEY | Period" /gt; lt;/xsl:copygt; lt;/xsl:otherwisegt; lt;/xsl:choosegt; lt;/xsl:for-eachgt; lt;/Documentgt; lt;/xsl:templategt;
lt;/xsl:таблица стилейgt;
Но он возвращает следующий вывод:
lt;Documentgt; lt;Rowgt; lt;KEYgt;NIKE|JB|APPAREL|MENSlt;/KEYgt; lt;Periodgt;Nov-21lt;/Periodgt; lt;/Rowgt; lt;Rowgt; lt;KEYgt;FASCINATE|JB|ACCESSORIES|LADIESlt;/KEYgt; lt;/Rowgt; lt;/Documentgt;
(Обратите внимание, что он не возвращает вложенное /Matches/Row/Period
во втором /Row
.
Я ожидаю получить следующий результат:
lt;Documentgt; lt;Rowgt; lt;KEYgt;NIKE|JB|APPAREL|MENSlt;/KEYgt; lt;Periodgt;Nov-21lt;/Periodgt; lt;/Rowgt; lt;Rowgt; lt;KEYgt;FASCINATE|JB|ACCESSORIES|LADIESlt;/KEYgt; lt;Periodgt;Nov-22lt;/Periodgt; lt;/Rowgt; lt;/Documentgt;
Что я делаю не так?
Комментарии:
1.
lt;xsl:variable name="period" select="/Period" /gt;
никогда ничего не будет выбрано, еслиPeriod
это не корневой элемент XML. Каков ожидаемый результат? Пожалуйста, добавьте это в свой вопрос.2. добавлен ожидаемый результат
Ответ №1:
неопределенные или нулевые значения не проверяются при использовании XSLT/XPath expression = null
, вы бы предпочли использовать (для наборов узлов) lt;xsl:when test="expression"gt;
, например lt;xsl:when test="Period"gt;
, чтобы для контекстного узла был хотя бы один Period
дочерний элемент или test="not(Period)"
чтобы проверить Period
, что дочернего элемента нет.
В конце концов, я бы предложил использовать сопоставление шаблонов на основе шаблона преобразования идентичности и поместить любые условия в шаблон соответствия (предикаты), но это другая проблема.
Ответ №2:
Получилось работать с этим XSLT:
lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://exampleincludednamespace.com/" exclude-result-prefixes="ns"gt; lt;xsl:output method="xml" omit-xml-declaration="yes" /gt; lt;xsl:template match="/"gt; lt;Documentgt; lt;xsl:for-each select="/Document/Row"gt; lt;xsl:choosegt; lt;xsl:when test="not(Period)"gt; lt;xsl:copygt; lt;xsl:copy-of select="KEY | Matches/Row/Period" /gt; lt;/xsl:copygt; lt;/xsl:whengt; lt;xsl:otherwisegt; lt;xsl:copygt; lt;xsl:copy-of select="KEY | Period" /gt; lt;/xsl:copygt; lt;/xsl:otherwisegt; lt;/xsl:choosegt; lt;/xsl:for-eachgt; lt;/Documentgt; lt;/xsl:templategt;
lt;/xsl:таблица стилейgt;
Спасибо руководству @MartinHonnen.
Ответ №3:
Я верю, что это может быть просто:
XSLT 1.0
lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"gt; lt;xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/gt; lt;xsl:template match="/Document"gt; lt;xsl:copygt; lt;xsl:for-each select="Row"gt; lt;xsl:copygt; lt;xsl:copy-of select="KEY | descendant::Period[1]" /gt; lt;/xsl:copygt; lt;/xsl:for-eachgt; lt;/xsl:copygt; lt;/xsl:templategt; lt;/xsl:stylesheetgt;