У меня возникли проблемы с преобразованием моего XML с помощью XSLT 1.0 (должно быть 1.0). У меня есть этот образец XML:
<feed xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:d = "http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xml:base = "http://servico.dados.gov.pt/v1/dgpj/">
<!-- Crimes registados 2014-1993 por localização -->
<title type = "text">Crimesregistados20141993porlocalizacao</title>
<entry>
<content>
<m:properties>
<d:RowKey>635951168253516361</d:RowKey>
<d:distritoinfracao>Aveiro</d:distritoinfracao>
<d:municipioinfracao>Agueda</d:municipioinfracao>
<d:a2014ncrimes>1392</d:a2014ncrimes>
<d:a2013ncrimes>1657</d:a2013ncrimes>
</m:properties>
</content>
<content>
<m:properties>
<d:RowKey>635951168253516361</d:RowKey>
<d:distritoinfracao>Algarve</d:distritoinfracao>
<d:municipioinfracao>Faro</d:municipioinfracao>
<d:a2014ncrimes>1300</d:a2014ncrimes>
<d:a2013ncrimes>1600</d:a2013ncrimes>
</m:properties>
</content>
<content>
<m:properties>
<d:RowKey>635950068253516361</d:RowKey>
<d:distritoinfracao>Aveiro</d:distritoinfracao>
<d:municipioinfracao>Ovar</d:municipioinfracao>
<d:a2014ncrimes>1999</d:a2014ncrimes>
<d:a2013ncrimes>1666</d:a2013ncrimes>
</m:properties>
</content>
</entry>
</feed>
У меня есть этот шаблон XSLT для удаления пространств имен, и он работает:
<xsl:template match = "*">
<xsl:element name = "{local-name()}">
<xsl:for-each select = "@*">
<xsl:attribute name = "{local-name()}">
<xsl:value-of select = "."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
И этот шаблон XSLT, который меняет мой XML так, как я хочу, но он работает, только если я удалю все пространства имен вручную:
<xsl:key name = "d" match = "properties" use = "distritoinfracao" />
<xsl:template match = "/*">
<xsl:copy>
<xsl:apply-templates select = "entry/content" />
</xsl:copy>
</xsl:template>
<xsl:template match = "entry/content">
<xsl:apply-templates select = "properties[generate-id(.) = generate-id(key('d',distritoinfracao)[1])]"/>
</xsl:template>
<xsl:template match = "properties[generate-id(.) = generate-id(key('d',distritoinfracao)[1])]">
<xsl:element name = "{translate(distritoinfracao,' ','_')}">
<xsl:for-each select = "key('d',distritoinfracao)">
<xsl:element name = "{translate(municipioinfracao,' ','_')}">
<xsl:copy-of select = "a2014ncrimes" />
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
Я не могу сочетать то и другое. Какие-либо предложения? Если можно, есть ли эквивалент LXML (python), который работает с XSLT 2.0?





Чтобы объединить оба файла XSLT, вы не можете избежать включения пространств имен в свой XSLT.
В этом ответе я просто включил пространства имен во второй XSLT и заменил простой xsl:copy на
<xsl:element name = "...">
<xsl:value-of select = "..." />
</xsl:element>
чтобы удалить его пространство имен. Таким образом вы можете удалить все пространства имен из элементов. Это нужно сделать отдельно для всех элементов пространства имен.
В результате получается XSLT-1.0:
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:d = "http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<xsl:output method = "xml" indent = "yes"/>
<xsl:key name = "d" match = "m:properties" use = "d:distritoinfracao" />
<xsl:template match = "/*">
<xsl:element name = "{local-name()}">
<xsl:apply-templates select = "entry/content" />
</xsl:element>
</xsl:template>
<xsl:template match = "entry/content">
<xsl:apply-templates select = "m:properties[generate-id(.) = generate-id(key('d',d:distritoinfracao)[1])]"/>
</xsl:template>
<xsl:template match = "m:properties[generate-id(.) = generate-id(key('d',d:distritoinfracao)[1])]">
<xsl:element name = "{translate(d:distritoinfracao,' ','_')}">
<xsl:for-each select = "key('d',d:distritoinfracao)">
<xsl:element name = "{translate(d:municipioinfracao,' ','_')}">
<xsl:element name = "a2014ncrimes">
<xsl:value-of select = "d:a2014ncrimes" />
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
И вывод:
<?xml version = "1.0"?>
<feed>
<Aveiro>
<Agueda>
<a2014ncrimes>1392</a2014ncrimes>
</Agueda>
<Ovar>
<a2014ncrimes>1999</a2014ncrimes>
</Ovar>
</Aveiro>
<Algarve>
<Faro>
<a2014ncrimes>1300</a2014ncrimes>
</Faro>
</Algarve>
</feed>
Ответить на этот вопрос было бы проще, если бы вы предоставили желаемый целевой XML.