在使用XSLT 1.0(必须为1.0)转换XML时遇到一些麻烦。 我有这个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>
我不能两者兼而有之。有什么建议么? 如果可以的话,是否有等效于XSLT 2.0的LXML(python)?
答案 0 :(得分: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>