Pergunta

Eu tenho um conjunto de arquivos XML que eu estou processando com uma transformação XSL. Eles têm um namespace padrão, por isso a minha transformação XSL deve conter a declaração:

xpath-default-namespace = "urn: CZ-RVV IS-VAV-XML-NS: data-1.2.2"

O problema é que este valor muda de tempos em tempos, e meu transformar de repente pára de funcionar, até que eu olhar um exemplo do novo arquivo, extrair este ID namespace e colocá-lo na transformação, em que a parar de trabalhar para transformar arquivos antigos. Existe uma maneira de passar este como um parâmetro, ou defini-lo de alguma forma em tempo de execução? Eu tentei as sintaxes de parâmetros que eu olhei para cima em vários tutoriais, mas nenhum deles trabalhou para este uso particular.

Eu tenho procurado todos os tipos de fóruns e encontrei referências a namespace agnóstico codificação de XSL, mas não descobriu como fazê-lo. livro Ian Williams' 'XSLT e XPath', afirma que o namespace padrão deve ser declarado, ou você não ganha nada no fluxo de saída, que é como ele tem trabalhado para mim. Mas eu realmente não quero ter que mudar isso com a mão regularmente, eu quero dar ao usuário algo que vai funcionar, sem a necessidade de constante atenção de mim.

A maneira confiável apenas 100% eu inventei até agora é usar uma linguagem de programação padrão para abrir a fonte de XML e XSL transformar como arquivos de texto, extrair o URI da fonte XML, colá-lo na transformação XSL, perto ambos os arquivos e, em seguida, finalmente, executar transformar o real. Isso funciona, mas é incrivelmente idiota, pelo menos para o meu gosto. Como posso lidar melhor com a mudança de namespaces padrão?

Pete

Foi útil?

Solução

O valor de XPath-default-namespace deve ser um estático URI, então você vai ter que pré-processar a folha de estilo se você quer que ele variar. Uma maneira de fazer isso seria usar XSLT. Aplique a seguinte meta-estilo ao seu estilo principal de cada vez, e depois invocar o resultado pré-processado em seu lugar.

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- Pass in the new namespace URI as a stylesheet parameter -->
  <xsl:param name="new-uri" required="yes"/>

  <!-- By default, copy everything as is -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- But update the value of @xpath-default-namespace -->
  <xsl:template match="@xpath-default-namespace">
    <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
      <xsl:value-of select="$new-uri"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

Este é um pouco de um caso de uso estranho, porém, porque namespaces não foram realmente concebido para ser tão dinâmico. Eles foram concebidos para qualificar nomes, ou seja, tornar-se parte de um nome. Quando você olha para ele dessa forma, namespaces dinâmicos não fazem muito sentido. Imagine um banco de dados cuja tabela e nomes de campo alterado arbitrariamente, de vez em quando, forçando-o a reescrever todos os seus scripts SQL para manter-se com as alterações. Isso é o que este é semelhante a.

Outras dicas

Você tentou definir um <xsl:param name="xpdn"/> parâmetro de estilo e usá-lo na declaração de estilo ou superior declaração modelo nível que em

<xsl:template match="...." xpath-default-namespace="$xpdn">

Eu não consigo encontrar nada na especificação que diz que isso não vai funcionar (mas não estou em posição de experimentá-lo agora).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top