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 № 1Moż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.