2014-07-14 3 views
0

У меня есть следующий XML-документ:Как удалить пустые узлы XML с помощью Java или XSLT

<?xml version="1.0" encoding="utf-8"?> 
<greatGrandParent> 
    <grandParent> 
     <parent> 
      <sibling>Fred</sibling> 
      <sibling>Max</sibling> 
      <sibling>Katie</sibling> 
     </parent> 
     <parent> 
      <sibling>Lindy</sibling> 
      <sibling>Richard</sibling> 
     </parent> 
     <parent> 
      <sibling /> 
     </parent> 
    </grandParent> 
    <grandParent> 
     <parent> 
      <sibling>Steve</sibling> 
      <sibling>Abbas</sibling> 
     </parent> 
     <parent> 
      <sibling>Kate</sibling> 
      <sibling>James</sibling> 
      <sibling>Ian</sibling> 
     </parent> 
    </grandParent> 
    <grandParent> 
     <parent> 
      <sibling /> 
     </parent> 
    </grandParent> 
</greatGrandParent> 

Мое требование - чтобы удалить узел XML, если все его дочерние элементы являются пустыми. Например, в приведенном выше XML,

  • У третьего родителя 1-го grandParent нет братьев и сестер. Следовательно, брат должен быть удален. А поскольку родитель не имеет братьев и сестер, родитель должен быть удален также из XML. Но grandParent все еще существовал бы, поскольку у него есть другие родители с братьями и сестрами.

  • Единственный родитель в третьем дедушке и бабушке не имеет братьев и сестер. Следовательно, брат должен быть удален. А поскольку родитель не имеет родного брата, родитель должен быть удален также. Поскольку grandParent не имеет дочерних элементов (родительский), grandParent также должен быть удален из XML.

Таким образом, полученный XML должен выглядеть следующим образом:

<?xml version="1.0" encoding="utf-8"?> 
<greatGrandParent> 
    <grandParent> 
     <parent> 
      <sibling>Fred</sibling> 
      <sibling>Max</sibling> 
      <sibling>Katie</sibling> 
     </parent> 
     <parent> 
      <sibling>Lindy</sibling> 
      <sibling>Richard</sibling> 
     </parent> 
    </grandParent> 
    <grandParent> 
     <parent> 
      <sibling>Steve</sibling> 
      <sibling>Abbas</sibling> 
     </parent> 
     <parent> 
      <sibling>Kate</sibling> 
      <sibling>James</sibling> 
      <sibling>Ian</sibling> 
     </parent> 
    </grandParent> 
</greatGrandParent> 

Я был бы рад, если кто-то может предложить мне решение, чтобы сделать это с помощью любого Java API или XSLT.

ответ

3

Вы можете использовать следующую XSLT для этого:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn xs"> 
     <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
     <xsl:template match="node()|@*"> 
       <xsl:if test="normalize-space(string(.)) != ''"> 
         <xsl:copy> 
           <xsl:apply-templates select="node()|@*"/> 
         </xsl:copy> 
       </xsl:if> 
     </xsl:template> 
</xsl:stylesheet> 

Чтобы получить представление о том, как она работает, выполните следующий XSLT, который дает вам дополнительный элемент на grandParent узле, а также прочитать этот небольшой учебник: http://www.xmlplease.com/xsltidentity

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

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

    <xsl:template match="grandParent"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*" /> 
      <childValues><xsl:value-of select="normalize-space(.)" /></childValues> 
      <xsl:apply-templates select="node()" /> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Блестящий! Ваш XSLT работает как шарм. Спасибо @Mark. Я подожду еще некоторое время, чтобы кто-нибудь предложил мне решение сделать то же самое с помощью Java. – abbasdgr8

+0

Буду рад, если вы также можете добавить объяснение тому, что он делает. Я понял, что он тестирует пустые узлы в XML, но я не понимаю, как он избавляется от дочерних и родительских элементов одновременно? – abbasdgr8

+1

@ abbasdgr8: Прежде всего у вас есть шаблон идентификации, который будет проходить через все узлы вашего XML-файла. Прочтите это: http://www.xmlplease.com/xsltidentity. Условие if проверяет, имеет ли текущий согласованный узел какое-либо значение (прямое значение, дочерние значения и т. Д.). Если он не имеет значения, пропустите весь узел (и его дочерние элементы) –

Смежные вопросы