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()
не только обрезает начальные и конечные пробелы, но также заменяет любые последовательности пробелов между другими символами на один пробел.