/ / Jak usunąć jeden znacznik po znalezieniu dopasowania - xml, shell

Jak usunąć jeden znacznik po znalezieniu dopasowania - xml, shell

Utknąłem w jednej sytuacji, w której 2 znaczniki XML przychodzą jeden po drugim w przypadkowym wzorze w pliku. W przypadku EG:

Niektóre tagi ......

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

mając na uwadze, że potrzebuję tylko drugiego occurencce identyfikatora TAG ServiceConfig wszędzie tam, gdzie jest on powtarzany. Na przykład powyżej, potrzebuję

<ServcieConfig Id ="345">.

Jak mogę to zrobić, np. Jak mogę usunąć wszystkie represywne znaczniki ServiceConfig?

PS.- Identyfikator nr jest różny dla wszystkich znaczników, które są represywne.

Dzięki,

Odpowiedzi:

0 dla odpowiedzi № 1

Możesz użyć do tego języka skryptowego lub nawet XSLT. Jednak oba rozwiązania będą musiały użyć xpath do adresowania węzłów będących przedmiotem zainteresowania, używam tego:

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

Wybiera wszystkie węzły, w których poprzednie rodzeństwo również ServiceConfig węzeł.


Pokaż teraz, jak usunąć te węzły za pomocą 1. XSLT i 2. Python. Dla przykładu użyłem następującego pliku 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>

Rozwiązanie oparte na 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>

Wykonaj to:

xsltproc delete.xsl test.xml

Rozwiązanie oparte na Pythonie

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

Wykonaj to:

python delete.py

Wyjście z obu rozwiązań to:

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

</node>
</data>

Możesz naprawić pustą linię za pomocą a ładna drukarka, Pominąłem to dla zwięzłości.