XSLT Копировать, Обрезать, Сортировать и Удалить в одном преобразовании

У меня есть следующий XML.

<oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/">
    <dc:title xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="hrv">Naslov rada</dc:title>
    <dc:date xmlns:dc="http://purl.org/dc/elements/1.1/">2001-01-01</dc:date>
    <dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Prezime, Ime</dc:creator>
    <dc:date xmlns:dc="http://purl.org/dc/elements/1.1/">2002-02-02</dc:date>
    <dc:relation xml:lang="eng">University of Zagreb. Academy of dramatic art. </dc:relation>
</oai_dc:dc>

и вывод, который мне нужен, это:

<dc>
    <creator>Prezime, Ime</creator>
    <date>2002-02-02</date> 
    <relation lang="eng">University of Zagreb. Academy of dramatic art.</relation>
    <title lang="hrv">Naslov rada</title>   
</dc>

Итак, что мне нужно сделать: удалить пространства имен из атрибутов и элементов. Я попробовал это с этим кодом, и он работает.

<xsl:template match="*">
 <xsl:element name="{local-name()}">
  <xsl:apply-templates select="@*|node()"/>
 </xsl:element>
</xsl:template>
<xsl:template match="@*">
 <xsl:attribute name="{local-name()}">
  <xsl:value-of select="."/>
 </xsl:attribute>
</xsl:template>

Далее мне нужно отсортировать элементы по имени элемента (и, возможно, по имени атрибута). Я сделал это с этим кодом, и он работает.

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

Затем мне нужно удалить все элементы, которые начинаются с "2001". Я сделал это с этим, и это работает.

<xsl:template match="/dc/date[starts-with(text(), '2001')]" />

И, наконец, я должен обрезать все текстовые значения в элементах. Обратите внимание:

<dc:relation xml:lang="eng">University of Zagreb. Academy of dramatic art. </dc:relation>

Я должен обрезать пустое пространство от конца (и начало), так что это:

<dc:relation xml:lang="eng">University of Zagreb. Academy of dramatic art.</dc:relation>

Так что моя проблема в том, что я не могу заставить его работать в одном XSLT вместе взятом. Идея состоит в том, чтобы: удалить префиксы (пространства имен) из элементов и атрибутов, которые определяют пространства имен, затем отсортировать элементы и удалить некоторые конкретные элементы (как в моем случае) и, наконец, обрезать все оставшиеся текстовые значения.

Я сделал все это, но с более чем одним преобразованием. Можно ли сделать это за один раз?

Я могу использовать только XSLT 1.0

1 ответ

Решение

С помощью

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
  xmlns:dc="http://purl.org/dc/elements/1.1/">

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

<xsl:template match="*">
 <xsl:element name="{local-name()}">
  <xsl:apply-templates select="@*">
      <xsl:sort select="local-name()"/>
  </xsl:apply-templates>
  <xsl:apply-templates select="node()">
      <xsl:sort select="local-name()"/>
  </xsl:apply-templates>
 </xsl:element>
</xsl:template>

<xsl:template match="@*">
 <xsl:attribute name="{local-name()}">
  <xsl:value-of select="."/>
 </xsl:attribute>
</xsl:template>

<xsl:template match="/oai_dc:dc/dc:date[starts-with(text(), '2001')]" />

<xsl:template match="text()[normalize-space()]">
    <xsl:value-of select="normalize-space()"/>
</xsl:template>

</xsl:transform>

создает вывод ( http://xsltransform.net/3NSSEvB)

<dc>
   <creator>Prezime, Ime</creator>
   <date>2002-02-02</date>
   <relation lang="eng">University of Zagreb. Academy of dramatic art.</relation>
   <title lang="hrv">Naslov rada</title>
</dc>

Обратите внимание, что использование normalize-space() не только обрезает начальные и конечные пробелы, но также заменяет любые последовательности пробелов между другими символами на один пробел.

Другие вопросы по тегам