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ąć?

Author: cc0, 2011-04-26

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 :

  1. Reguła tożsamości / szablon kopiuje wszystkie węzły "as-is".

  2. 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.

  3. 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.

  4. 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.

 12
Author: Dimitre Novatchev,
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ź

 4
Author: MarcoS,
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