XSLT - jak zachować tylko pożądane elementy z XML
Mam wiele plików XML zawierających wiele napowietrznych. Chcę zachować tylko około 20 konkretnych elementów i odfiltrować Wszystko inne. Znam wszystkie nazwy elementów, które chcę zachować, wiem też, czy są one elementami dziecięcymi i kim są ich rodzice. Te elementy, które chcę zachować po transformacji, muszą nadal mieć swoje oryginalne hierarchiczne rozmieszczenie.
Np. chcę zachować tylko
<ns:currency>
In;
<ns:stuff>
<ns:things>
<ns:currency>somecurrency</ns:currency>
<ns:currency_code/>
<ns:currency_code2/>
<ns:currency_code3/>
<ns:currency_code4/>
</ns:things>
</ns:stuff>
Oraz zrób to tak;
<ns:stuff>
<ns:things>
<ns:currency>somecurrency</ns:currency>
</ns:things>
</ns:stuff>
Jaki byłby najlepszy sposób na zbudowanie XSLT, aby to osiągnąć?
2 answers
Ta ogólna transformacja :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="some:ns">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<ns:WhiteList>
<name>ns:currency</name>
<name>ns:currency_code3</name>
</ns:WhiteList>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"*[not(descendant-or-self::*[name()=document('')/*/ns:WhiteList/*])]"/>
</xsl:stylesheet>
Po zastosowaniu na dostarczonym dokumencie XML (z dodaną definicją przestrzeni nazw, aby była dobrze uformowana):
<ns:stuff xmlns:ns="some:ns">
<ns:things>
<ns:currency>somecurrency</ns:currency>
<ns:currency_code/>
<ns:currency_code2/>
<ns:currency_code3/>
<ns:currency_code4/>
</ns:things>
</ns:stuff>
Tworzy pożądany rezultat (zachowane są białe elementy i ich relacje strukturalne):
<ns:stuff xmlns:ns="some:ns">
<ns:things>
<ns:currency>somecurrency</ns:currency>
<ns:currency_code3/>
</ns:things>
</ns:stuff>
Wyjaśnienie :
Reguła tożsamości / szablon kopiuje wszystkie węzły "as-is".
Arkusz stylów zawiera element
<ns:WhiteList>
najwyższego poziomu, którego<name>
dzieci określają wszystkie nazwy elementów z białej listy - elementy, które mają być zachowane z ich strukturalnymi relacjami w dokumencie.Element
<ns:WhiteList>
najlepiej przechowywać w osobnym dokumencie, aby nie trzeba było edytować bieżącego arkusza stylów z nowymi nazwami. Tutaj biała lista jest w tym samym arkuszu stylów tylko dla wygody.Jeden pojedynczy szablon zastępuje szablon tożsamości. Nie przetwarza (usuwa) żadnego elementu, który nie jest biały-notowany i nie ma potomka, który jest biały-notowany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-26 13:17:41
W XSLT zazwyczaj nie usuwasz elementów, które chcesz upuścić, ale kopiujesz elementy, które chcesz zachować:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://www.example.com/ns#"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/ns:stuff">
<xsl:copy>
<xsl:apply-templates select="ns:things"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns:things">
<xsl:copy>
<xsl:apply-templates select="ns:currency"/>
<xsl:apply-templates select="ns:currency_code3"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns:currency">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="ns:currency_code3">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
Powyższy przykład kopiuje tylko currency
i currency_code3
. Wyjście jest następujące:
<?xml version="1.0" encoding="UTF-8"?>
<ns:stuff xmlns:ns="http://www.example.com/ns#">
<ns:things>
<ns:currency>somecurrency</ns:currency>
<ns:currency_code3/>
</ns:things>
</ns:stuff>
Uwaga: dodałem deklarację przestrzeni nazw dla Twojego prefiksu ns
.
Jeśli chcesz skopiować wszystko oprócz kilku elementów, możesz zobaczyć tę odpowiedź
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:01:54