XSLT - Как сохранить только нужные элементы из XML - PullRequest
7 голосов
/ 26 апреля 2011

У меня есть несколько файлов XML, содержащих много накладных расходов. Я хочу сохранить только около 20 конкретных элементов и отфильтровать все остальное. Я знаю все названия элементов, которые я хочу сохранить, я также знаю, являются ли они дочерними элементами и кто их родители. Эти элементы, которые я хочу сохранить после преобразования, должны по-прежнему иметь свое первоначальное иерархическое расположение.

например. Я хочу сохранить ТОЛЬКО

<ns:currency>

в;

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

И пусть это будет выглядеть так;

<ns:stuff>
 <ns:things>
  <ns:currency>somecurrency</ns:currency>
 </ns:things>
</ns:stuff>

Каков наилучший способ построения XSLT для достижения этой цели?

Ответы [ 2 ]

14 голосов
/ 26 апреля 2011

Это общее преобразование :

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

при применении к предоставленному документу XML (с добавлением определения пространства имен, чтобы сделать его правильно сформированным):

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

дает желаемый результат (элементы из белого списка и их структурные связи сохраняются):

<ns:stuff xmlns:ns="some:ns">
   <ns:things>
      <ns:currency>somecurrency</ns:currency>
      <ns:currency_code3/>
   </ns:things>
</ns:stuff>

Объяснение

  1. Правило / шаблон идентификации копирует все узлы "как есть".

  2. Таблица стилей содержит элемент верхнего уровня <ns:WhiteList>, чьи дочерние элементы <name> определяют имена всех элементов в белом списке - элементы, которые должны быть сохранены с их структурными связями в документе.

  3. Элемент <ns:WhiteList> лучше всего хранить в отдельном документе, чтобы текущая таблица стилей не нуждалась в редактировании с новыми именами. Здесь белый список находится в той же таблице стилей просто для удобства.

  4. Один шаблон переопределяет шаблон идентификации. Он не обрабатывает (удаляет) элементы, не занесенные в белый список и не имеющие потомков, занесенных в белый список.

6 голосов
/ 26 апреля 2011

В XSLT вы обычно не удаляете элементы, которые хотите удалить, но копируете элементы, которые хотите сохранить:

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

В приведенном выше примере копируются только currency и currency_code3. Вывод выглядит следующим образом:

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

Примечание: я добавил декларацию пространства имен для вашего префикса ns.

Если вы хотите скопировать все, кроме нескольких элементов, вы можете увидеть этот ответ

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