Como posso usar a expressão XPath “document('')” em um .NET XsltCompiledTransform?Eu devo?

StackOverflow https://stackoverflow.com/questions/4405622

  •  25-09-2019
  •  | 
  •  

Pergunta

Atualmente estou trabalhando em um site onde enviamos XML + XSLT para clientes que o suportam, para economizar largura de banda.No entanto, se um cliente não oferecer suporte, faremos a transformação no lado do servidor e enviaremos o HTML resultante.

No meu XSLT, gostaria de usar um XPath muito parecido com:

document('')//xsl:variable[@name='test']

(para retornar um conjunto de nós).Isso funciona muito bem no Firefox e no IE, mas não funciona com o XsltCompiledTransform - ele me diz:

Esta operação não é suportada para um URI relativo.

Parece que o erro está ocorrendo em XmlUrlResolver - sei que posso passar um personalizado desses, mas, além disso, não tenho certeza de onde devo procurar.Alguém pode me dar alguma dica de como posso fazer essa expressão funcionar?Fico feliz em usar algumas extensões MSXSL se necessário - afinal, o código só seria visto no lado do servidor.

Em uma observação mais geral: é comum fazer esse tipo de consulta XPath?Estou caindo em alguma armadilha XSLT gigante que não conheço?Isso vai fazer algo maluco, como parar navegadores lentos?

Foi útil?

Solução

Inicie a transformação usando uma instância construída adequadamente de Configurações Xslt, para que a função de documento seja permitida.

Aqui está um exemplo:

// Create the XsltSettings object with the document fn allowed.
XsltSettings settings = new XsltSettings(true,false);

// Create the XslCompiledTransform object and load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("sort.xsl", settings, new XmlUrlResolver());

Sua outra pergunta:

Em uma nota mais geral- é comum fazer esse tipo de consulta XPath?Estou caindo em alguma armadilha gigante do XSLT que não estou ciente?Isso vai fazer algo louco como os navegadores lentos da web parar?

A única armadilha é que isso pode fazer com que a folha de estilo XSLT seja analisada novamente e esta é uma operação relativamente lenta.

Mais preocupante é o seu uso do // abreviatura que quase certamente causará problemas de desempenho.

É muito melhor usar esse truque apenas para variáveis ​​globais e depois usar esta expressão:

document('')/*/xsl:variable[@name='test']

Por fim, caso você não esteja preocupado em perder a portabilidade entre processadores XSLT 1.0, é mais eficiente utilizar o xxx:node-set() função de extensão dependente da implementação para converter o RTF da variável em um conjunto de nós regular.Aqui, alguém poderia usar exslt:node-set() desde que o processador XSLT implemente EXSLT.Isso ainda atinge um grau relativamente grande de portabilidade, porque muitos processadores XSLT, incluindo XslCompiledTransform, suportam exslt:node-set().

Outras dicas

Não consegui encontrar uma solução que me permita usar o documento (''), mas como tudo o que estou usando é obter uma variável para avaliar um conjunto de nós, estou ajustando o XML antes de processar No lado do servidor, para mudar:

document('')//xsl:variable[@name='test']

para:

msxsl:node-set($test)

Não é exatamente a solução mais graciosa, mas funciona para meus propósitos.

Você já tentou usar

document('')//xsl:variable[@name='test']

? Ou seja, use uma string de comprimento zero como o argumento para document(), em vez de não transmitir argumentos. De acordo com a especificação, document() Deve ter pelo menos um argumento. Estou surpreso que o Firefox e o IE sejam LAX sobre isso. Mas isso poderia explicar por que o XSLCompiledTransform está infeliz.

Por outro '' pode não funcionar (é considerado um URI relativo). É possível que, como esteja compilando a transformação, não é conveniente fornecer acesso a uma representação de árvore da folha de estilo. "Um processador XSLT não é necessário para suportar nenhum esquema de URI específico. A documentação para um processador XSLT deve especificar quais esquemas de URI o processador XSLT suporta".

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