Como remover nós XML duplicados usando XSLT

votos
3

Eu tenho um arquivo XML extremamente longa, como

<Root>
   <ele1>
      <child1>context1</child1>
      <child2>test1</child2>
      <child1>context1</child1>
   </ele1>

   <ele2>
      <child1>context2</child1>
      <child2>test2</child2>
      <child1>context2</child1>
   </ele2>
   <ele3>...........<elen>
</Root>

Agora eu quero remover todo o segundo <child1>em cada <ele>usando XSLT, é possível? O resultado seria assim:

<Root>
   <ele1>
      <child1>context1</child1>
      <child2>test1</child2>
   </ele1>

   <ele2>
      <child1>context2</child1>
      <child2>test2</child2>
   </ele2>
       <ele3>...........<elen>
</Root>

Thank u, BR

Allen

Publicado 10/12/2008 em 12:00
fonte usuário
Em outras línguas...                            


3 respostas

votos
4

Esta questão requer uma resposta pouco mais detalhada do que apenas apontando para uma boa Muenchian Agrupamento fonte.

A razão é que o agrupamento necessário exige para identificar tanto os nomes de todos os filhos de um "ele [SomeString]" elemento e seus pais . Tal agrupamento requer para definir uma chave que é exclusivamente definido por ambas as fontes originais, geralmente através de concatenação.

Esta transformação :

<Xsl: stylesheet version = "1.0"
 xmlns: xsl = "http://www.w3.org/1999/XSL/Transform">
 <Xsl: output omitir-xml-declaração = "yes" indent = "yes" />

 <Xsl: key name = jogo "kElByName" = "*"
      use = "concat (gerar-id (..), '+', name ())" />

    <Xsl: template match = "node () | @ *">
      <Xsl: copy>
        <Xsl: apply-templates escolha = "node () | @ *" />
      </ Xsl: copy>
    </ Xsl: template>

    <Xsl: template match = "* [começa-com (nome (), 'ele')]">
      <Xsl: copy>
        <Xsl: copy-of select = "@ *" />
        <Xsl: apply-templates select =
         "* [Gerar-id ()
           =
            gerar-id (chave ( 'kElByName',
                        concatenação (gerar-id (..), '+', nome ())
                        ) [1])
            ]"
         />
      </ Xsl: copy>
    </ Xsl: template>
</ Xsl: stylesheet>

quando aplicado sobre este documento XML :

<Root>
    <Ele1>
        <Child1> context1 </ child1>
        <Child2> test1 </ child2>
        <Child1> context1 </ child1>
    </ Ele1>
    <Ele2>
        <Child1> context2 </ child1>
        <Child2> test2 </ child2>
        <Child1> context2 </ child1>
    </ Ele2>
    <Ele3>
        <Child2> context2 </ child2>
        <Child2> test2 </ child2>
        <Child1> context1 </ child1>
    </ Ele3>
</ Root>

produz o resultado desejado :

<Root>
    <Ele1>
        <Child1> context1 </ child1>
        <Child2> test1 </ child2>
    </ Ele1>
    <Ele2>
        <Child1> context2 </ child1>
        <Child2> test2 </ child2>
    </ Ele2>
    <Ele3>
        <Child2> context2 </ child2>
        <Child1> context1 </ child1>
    </ Ele3>
</ Root>
Respondeu 11/12/2008 em 03:50
fonte usuário

votos
1

Se fornecido XML do OP é representante de seu / sua pergunta (e o segundo <child1> dentro de cada <ele*>elemento deve ser removido), então Muenchian Agrupamento não é necessário:

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <!-- Remove the 2nd <child1> element from each <ele*> element -->
  <xsl:template match="*[starts-with(name(), 'ele')]/child1[2]" />

</xsl:stylesheet>

Quando executado contra o XML fornecido:

<?xml version="1.0" encoding="UTF-8"?>
<Root>
  <ele1>
    <child1>context1</child1>
    <child2>test1</child2>
    <child1>context1</child1>
  </ele1>
  <ele2>
    <child1>context2</child1>
    <child2>test2</child2>
    <child1>context2</child1>
  </ele2>
</Root>

... o resultado desejado é produzido:

<?xml version="1.0" encoding="UTF-8"?>
<Root>
  <ele1>
    <child1>context1</child1>
    <child2>test1</child2>
  </ele1>
  <ele2>
    <child1>context2</child1>
    <child2>test2</child2>
  </ele2>
</Root>
Respondeu 20/05/2012 em 03:23
fonte usuário

votos
-1

Seu xml e pergunta são uma espécie de claro, mas o que você está procurando é comumente chamado de Muenchian Agrupamento método - é outra maneira de perguntar para nós distintos. Com as teclas apropriadas isso pode ser feito de forma muito eficiente.

Respondeu 10/12/2008 em 12:07
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more