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 № 1Você 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.