/ / Como excluir uma tag após a correspondência ser encontrada - xml, shell

Como excluir uma tag após a correspondência ser encontrada - xml, shell

Eu estou preso em uma situação como esta, onde duas tags XML estão chegando um após o outro em padrão aleatório em um arquivo. Para o EG:

Algumas tags ......

<ServiceConfig Id ="403">
<ServiceConfig Id ="345">

enquanto eu preciso apenas da segunda ocorrência do TAG ServiceConfig ID onde quer que ele esteja se repetindo. Como para acima, por exemplo, eu preciso

<ServcieConfig Id ="345">.

Como posso fazer isso, ou seja, como posso excluir todas as tags Repititive ServiceConfig?

PS.- O Id não é diferente para todas as tags que são repetitivas.

Obrigado,

Respostas:

0 para resposta № 1

Você pode usar uma linguagem de script ou mesmo XSLT para isso. No entanto, as duas soluções precisariam usar o xpath para endereçar os nós de interesse. Estou usando este:

//ServiceConfig[name(preceding-sibling::*[1]) = "ServiceConfig"]

Seleciona todos os nós onde o irmão anterior também é um ServiceConfig nó.


Agora mostrará como remover esses nós usando 1. XSLT e 2. Python. Para o exemplo, usei o seguinte arquivo xml:

test.xml

<?xml version="1.0"?>
<data>
<node>
<sub id="1" />
<some />
<sub id="2" />
</node>
<node>
<some />
<sub id="3" />
<sub id="4" />
</node>
</data>

Solução baseada em XSLT

delete.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="//sub[name(preceding-sibling::*[1]) = "sub"]">
<!-- empty, leads to tag removal -->
</xsl:template>
<!-- identy transformation of the remaing node -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Execute:

xsltproc delete.xsl test.xml

Solução baseada em Python

delete.py

import libxml2

doc = libxml2.parseFile("test.xml")
ctx = doc.xpathNewContext()
res = ctx.xpathEval("//sub[name(preceding-sibling::*[1]) = "sub"]")

for item in res:
item.unlinkNode()

print doc

Execute:

python delete.py

A saída de ambas as soluções é:

<?xml version="1.0"?>
<data>
<node>
<sub id="1"/>
<some/>
<sub id="2"/>
</node>
<node>
<some/>
<sub id="3"/>

</node>
</data>

Você pode consertar a linha em branco usando um impressora bonita, Omiti isso por brevidade.