преобразование дат из гггг-мм-дд в дд / мм / гггг с учетом нулевых или пустых дат в xslt - PullRequest
3 голосов
/ 08 июня 2011

Я хотел изменить порядок дат с гггг-мм-дд на дд / мм / гггг, но для обслуживания нулевых или пустых дат, я использовал код

<!--         Data Submitted -->
<xsl:template match="data_submitted">
<data_submitted>
    <xsl:if test="data_submitted != ''">
            <xsl:value-of select=
           "concat(substring(.,9), '/',
                  (substring(.,6,2)), '/',
                 substring(.,1,4))"
           />
    </xsl:if>
</data_submitted>   
</xsl:template>
<!--                                           -->

, но это вообще пропустило даты.Исключение результата привело к появлению нулевых дат как // в моем результате.Я уверен, что, возможно, получил неправильное место или что-то в этом роде, но я хочу, чтобы тег отображался, даже если он пуст.

Есть предложения?

Обновление:

Приношу извинения всем, я должен был дать исходный xml, так как я тестировал ноль или пусто, и на самом деле в элементе были пробелы, поэтому мой первоначальный перевод сработал бы, если бы япросто введите количество пробелов.Исходный xml: data_submitted> </data_submitted> с 8 пробелами.test="data_submitted != ' '" - это то, что требовалось, или: test=".!= ''", каждый с 8 пробелами.

Ответы [ 4 ]

1 голос
/ 08 июня 2011

Ваша ошибка проверяет, имеет ли какой-либо data_submitted дочерний элемент текущего (data_submitted) непустое строковое значение .Я предполагаю, что элементы data_submitted в исходном XML-документе вообще не имеют дочерних элементов data_submitted.

Вот полное и краткое решение вашей проблемы, просто переопределяющее личностьправило / шаблон:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

    <xsl:template match="data_submitted/text()">
        <xsl:value-of select=
        "concat(substring(.,9),
                 '/',
                 substring(.,6,2),
                 '/',
                 substring(.,1,4)
             )
  "/>
    </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к следующему документу XML :

<t>
  <a/>
  <b>
     <data_submitted>2011-06-07</data_submitted>
     <data_submitted/>
    </b>
    <data_submitted>1912-05-12</data_submitted>
    <c/>
</t>

желаемый, правильный результат получается :

<t>
   <a/>
   <b>
      <data_submitted>07/06/2011</data_submitted>
      <data_submitted/>
   </b>
   <data_submitted>12/05/1912</data_submitted>
   <c/>
</t>

Объяснение :

  1. Шаблон идентификации копирует каждый узел "как есть"

  2. Один шаблон переопределяет правило идентификации - для дочерних элементов текстового узла любого элемента data_submitted.Код здесь производит искомую преобразованную дату.Все остальные узлы, включая пустые элементы data_submitted, обрабатываются правилом идентификации и копируются «как есть» на выход.

Помните : Inво многих случаях нет необходимости использовать какие-либо условные инструкции XSLT.

Используйте возможности шаблонов XSLT и сопоставление с образцом.

1 голос
/ 08 июня 2011

Есть "крошечная" ошибка .. Сравните с этим (исправленным) преобразованием, если вы его получите:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="data_submitted">
        <data_submitted>
            <xsl:variable name="year" select="substring-before(.,'-')"/>
            <xsl:variable name="month" select="substring-before(substring-after(.,'-'),'-')"/>
            <xsl:variable name="day" select="substring-after(substring-after(.,'-'),'-')"/>

            <xsl:if test=".!=''">
                <xsl:value-of select=
                    "concat($day,'/',
                    $month,'/',
                    $year)"
                    />
            </xsl:if>
        </data_submitted>   
    </xsl:template>

</xsl:stylesheet>

Применяется к этому примеру ввода:

<data>
    <data_submitted>
        yyyy-mm-dd
    </data_submitted>
    <data_submitted/>
</data>

Возвращает:

<data>
   <data_submitted>dd/mm/yyyy</data_submitted>
   <data_submitted/>
</data>

Есть ошибка?

Шаблон уже находится в контексте data_submitted, поэтому внутри теста шаблона вам просто нужно ., чтобы сослаться на соответствующийelement.

Однако я предлагаю вам протестировать пустые text() узлы в приведенном выше шаблонном контексте следующим образом:

test="boolean(./text())"

или (то же самое в вашем контексте)

test="boolean(text())"

Это вернет false, если и только если длина текстовой строки равна 0.

1 голос
/ 08 июня 2011

Вы не объяснили, что вы подразумеваете под "нулем или пустым". Ваш шаблон должен работать, если элемент data_submitted существует и не имеет содержимого, но он не будет работать, если элемент data_submitted не существует. Чтобы справиться с небытием и пустотой, замените data_submitted != '' на not(data_submitted = ''). На самом деле, как правило, не используйте "! =" В XSLT, если вы не являетесь экспертом и точно не знаете, что это значит.

0 голосов
/ 08 июня 2011

Обычно при тестировании, если узел существует, вы помещаете выражение xpath в свой оператор "test". Не видя ваш xml, я думаю, что вы можете просто удалить "! = ''", И все будет в порядке.


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...