Как сгладить этот XML с помощью XSLT - PullRequest
1 голос
/ 04 декабря 2008

ВХОД

<logs>
<logentry revision="648">
<author>nshmyrev</author> 
<date>2008-09-21T19:43:10.819236Z</date> 
<paths>
<path action="M">/trunk/po/ru.pi</path> 
</paths>
<msg>2008-09-21 Nickolay V. Shmyrev nshmyrev@yandex.ru * ru.po: Updated Russian translation.</msg> 
</logentry>
<logentry revision="647">
<author>ckirbach</author> 
<date>2008-09-21T16:25:58.369324Z</date> 
<paths>
<path action="M">/trunk/po/de.po</path> 
<path action="M">/trunk/po/ChangeLog</path> 
</paths>
<msg>* de.po: Updated German translation.</msg> 
</logentry>
<logs>

до

<logs>
<LogEntry revision="647" author = "ckirbach" action="M">/trunk/po/de.po</LogEntry>
<LogEntry revision="647" author = "ckirbach" action="M">/trunk/po/ChangeLog</LogEntry>
</logs

Далее, я хочу игнорировать все пути с расширением, скажем '.pi'

Ответы [ 2 ]

1 голос
/ 04 декабря 2008

Решение Аластера дает неправильный результат : значение созданного атрибута "author" равно "nshmyrev", но оно должно быть: "ckirbach".

Решение, приведенное ниже, проверено на правильность работы.

Вот решение, которое работает для различных расширений, которые должны игнорироваться (указано в глобальном <xsl:param/>).

Это преобразование:

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

 <xsl:param name="pIgnExt" select="'.pi'"/>
 <xsl:variable name="vExtLen"
      select="string-length($pIgnExt)"/>

    <xsl:template match="logs">
      <logs>
        <xsl:apply-templates select="*/*/path"/>
      </logs>
    </xsl:template>

    <xsl:template match="path">
    <xsl:variable name="vthisLen"
         select="string-length(.)"/>
      <xsl:if test=
        "not(substring(.,$vthisLen -$vExtLen +1)
            =
             $pIgnExt
             )">
        <LogEntry revision="{../../@revision}"
                  author="{../../author}"
                  action="{@action}">
        <xsl:copy-of select="node()"/>
      </LogEntry>
      </xsl:if>
    </xsl:template>
</xsl:stylesheet>

при применении к исходному документу XML (исправлено, чтобы быть правильно сформированным!):

<logs>
    <logentry revision="648">
        <author>nshmyrev</author>
        <date>2008-09-21T19:43:10.819236Z</date>
        <paths>
            <path action="M">/trunk/po/ru.pi</path>
        </paths>
        <msg>2008-09-21 Nickolay V. Shmyrev nshmyrev@yandex.ru * ru.po: Updated Russian translation.</msg>
    </logentry>
    <logentry revision="647">
        <author>ckirbach</author>
        <date>2008-09-21T16:25:58.369324Z</date>
        <paths>
            <path action="M">/trunk/po/de.po</path>
            <path action="M">/trunk/po/ChangeLog</path>
        </paths>
        <msg>* de.po: Updated German translation.</msg>
    </logentry>
</logs>

дает желаемый результат:

<logs>
   <LogEntry revision="647" author="ckirbach" action="M">/trunk/po/de.po</LogEntry>
   <LogEntry revision="647" author="ckirbach" action="M">/trunk/po/ChangeLog</LogEntry>
</logs>

Обратите внимание, что это можно использовать в качестве реализации в XPath 1.0 функции end-with () , которая доступна только в XPath 2.0.

1 голос
/ 04 декабря 2008

Как насчет

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/logs">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="text()"/>

  <xsl:template match="path[substring(.,string-length()-2)!='.pi']">
    <LogEntry revision="{ancestor::logentry/@revision}"
              author="{preceding::author/text()}"
              action="{@action}">
      <xsl:copy-of select="text()"/>
    </LogEntry>
  </xsl:template>

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