XSLT — как скопировать элемент XML без участия одного из его внуков?

#xml #xslt

#xml #xslt

Вопрос:

У меня есть xml, из которого я пытаюсь скопировать все содержимое < a >, без элементов < ToRemove > и текста внутри.

     <a>
      <b>
      ...
      </b>
      <c>
        <d>
          <e>
            <ToRemove someAttributes> value </ToRemove>
          </e>
          <f>
            <ToRemove someAttributes> value </ToRemove>
            <m/>
          </f>
        ...
        </d>
      </c>
    </a> 
    <z/>
    <w/>
  

У меня есть уже существующий xlst, который я пытаюсь адаптировать, но ни один из методов, которые я пробовал, не удалил его из результата.

     <xsl:template match="/">
          <xsl:apply-templates select="a"/>
      </xsl:template>
      
      <xsl:template match="a">
        <someTag1>
            <someTag2>
              <xsl:copy-of select="."/>
            </someTag2>
        </someTag1>
      </xsl:template>
    
      <xsl:template match="ToRemove"/> ```

The result should be:
  
 <someTag1>
    <someTag2>
        <a>
          <b>
          ...
          </b>
          <c>
            <d>
              <e/>
              <f>
                <m/>
              </f>
            ...
            </d>
          </c>
        </a> 
    </someTag2>
</someTag1>
  

Ответ №1:

Вот рабочий пример:

Ввод XML:

 <?xml version="1.0" encoding="UTF-8"?>
<root>
  <parent>
     <child>
       <grandchild/>
     </child>
  </parent>
</root>
  

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

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
  <xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="*">
   <xsl:copy>
     <xsl:apply-templates />
   </xsl:copy>
</xsl:template>

<xsl:template match="child">
        <someTag1>
            <someTag2>
                <xsl:copy>
                   <xsl:apply-templates />
                </xsl:copy>
            </someTag2>
        </someTag1>
</xsl:template>

<xsl:template match="grandchild" />

</xsl:stylesheet>
  

Вывод:

 <?xml version="1.0" encoding="UTF-8"?>
<root>
  <parent>
     <someTag1>
       <someTag2>
          <child>
       
          </child>
       </someTag2>
     </someTag1>
  </parent>
</root>
  

Если вы хотите сделать someTag1 в качестве корня вашего выходного документа, добавьте, template который будет просто делать apply-templates без копии, подобной этой:

 <xsl:template match="grandparent | parent">
   <xsl:apply-templates />
</xsl:template>
  

Комментарии:

1. Используйте <xsl:copy-of select="@*" /> для копирования атрибутов. <xsl:соответствие шаблону="дочерний элемент"> <someTag1> <someTag2> <xsl:копировать> <xsl:копировать из select="@*" /> <xsl:применить шаблоны /> </xsl:копировать> </someTag2> </someTag1> </xsl:шаблон>