Объедините эти два шаблона XSLT - PullRequest
0 голосов
/ 02 ноября 2018

У меня возникли проблемы с преобразованием 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?

1 Ответ

0 голосов
/ 02 ноября 2018

Чтобы объединить оба 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>
...