2016-02-12 2 views
2

Я пытаюсь очистить файл с произвольными именами элементов, который выглядит как:Рекурсивный Пустой узел очистки

<root> 
    <nodeone> 
     <subnode>with stuff</subnode> 
    </nodeone> 
    <nodeone> 
     <subnode>with other stuff</subnode> 
    </nodeone> 
    <nodeone> 
     <subnode /> 
    </nodeone> 
</root> 

в файл, который выглядит как:

<root> 
    <nodeone> 
     <subnode>with stuff</subnode> 
    </nodeone> 
    <nodeone> 
     <subnode>with other stuff</subnode> 
    </nodeone> 
</root> 

Вы можете видеть, что все «узла», в котором исчезли пустые дети. Я использовал решение, которое удаляет пустой <subnode>, но сохраняет <nodeone>. Желаемый результат состоит в том, что оба этих элемента удалены.

Моя текущая попытка решения (который не делает ровно ничего) является:

<?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="node()|@*"> 
     <xsl:call-template name="backwardsRecursion"> 
      <xsl:with-param name="elementlist" select="/*/node/*[normalize-space()]"/> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="backwardsRecursion"> 
     <xsl:param name="elementlist"/> 

     <xsl:if test="$elementlist"> 
      <xsl:apply-templates select="$elementlist[last()]"/> 

      <xsl:call-template name="backwardsRecursion"> 
       <xsl:with-param name="elementlist" select="$elementlist[position() &lt; last()]"/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="/*/node/*[normalize-space()]"> 
      <xsl:value-of select="."/> 
    </xsl:template> 
</xsl:stylesheet> 

XSLT это не то, что я использую очень часто, так что я немного потерял.

+1

Это хорошо задаваемый вопрос, на мой взгляд. Понятно, что вы пытались найти способ рекурсивно вызывать шаблоны, как и на других языках программирования. Тем не менее, красота XSLT (если есть такая вещь) заключается в том, что она рекурсивно применяет шаблоны по умолчанию, а код, который вы пишете, обычно останавливает или изменяет процесс рекурсии - как показано ниже. –

ответ

2

Начать с тождественным преобразованием,

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

и добавить шаблон хлюпать элементы без signficant, не пространственно-нормированных строковых значений,

<xsl:template match="*[not(normalize-space())]"/> 

, и вы получите результаты, которые вы ищете ,

Итого:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="*[not(normalize-space())]"/> 

</xsl:stylesheet> 
Смежные вопросы