Как удалить ненужные элементы и атрибуты из файла XML с помощью XSLT - PullRequest
4 голосов
/ 13 мая 2011

У меня есть XML-файл, я хочу скопировать его как есть, но я хочу отфильтровать некоторые нежелательные элементы и атрибуты, например, вот исходный файл:

<root>
<e1 att="test1" att2="test2"> Value</e1>
<e2 att="test1" att2="test2"> Value 2 <inner class='i'>inner</inner></e2>
<e3 att="test1" att2="test2"> Value 3</e3>

</root>

После фильтрации (Элемент e3 и атрибут att2 удалены):

<root>
<e1 att="test1" > Value</e1>
<e2 att="test1" > Value 2 <inner class='i'>inner</inner></e2>
</root>

Примечания:

  • Я предпочитаюиспользовать ( для каждого элемента вместо apply-templates , если это возможно)
  • У меня есть некоторые проблемы с xsl: element и xsl: attribute , поскольку я не могу написать имя текущего узла

Спасибо

Ответы [ 2 ]

9 голосов
/ 13 мая 2011

Я знаю, что вы бы предпочли использовать for-each, но почему бы не использовать преобразование идентичности, а затем переопределить этот шаблон тем, что вы не хотите сохранять?

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="e3|@att2"/>

</xsl:stylesheet>

производит:

<root>
   <e1 att="test1"> Value</e1>
   <e2 att="test1"> Value 2 <inner class="i">inner</inner>
   </e2>
</root>
1 голос
/ 13 мая 2011

Как показал @DevNull, использовать преобразование идентичности гораздо проще и менее многословно.В любом случае, вот одно из возможных решений с for-each и без apply-templates, как вы и просили:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="/root">
   <root>
    <xsl:for-each select="child::node()">
     <xsl:choose>
      <xsl:when test="position()=last()-1"/>
      <xsl:otherwise>
       <xsl:copy>
        <xsl:copy-of select="@att"/>
        <xsl:copy-of select="child::node()"/>
       </xsl:copy>
      </xsl:otherwise>
    </xsl:choose>
   </xsl:for-each>
  </root>
</xsl:template>


Примечание об использовании преобразования идентификаторов

Есливаша ситуация на самом деле выглядит так, я имею в виду неизвестное имя элементов, @DevNull не будет работать, и вам нужно что-то более общее, например:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
   <xsl:strip-space elements="*"/>

    <xsl:template match="node()|@*">
     <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
    </xsl:template>

    <xsl:template match="root/child::node()[position()=last()]|@att2"/>

</xsl:stylesheet>

Это решение будет работать даже с последнимиэлементы e4 или e1000.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...