2016-03-21 1 views
0

Ответы могут быть XSLT 2.0 или 3.0; Saxon EE анализаторРазбирайте строку в XML и xPath в нее - XSLT 2 или 3

Данный пример XML:

<theRootNode xmlns="http://myNamespace"> 
    <xml> 
     &lt;Company&gt; 
      &lt;TaxIdentity&gt; 
       &lt;id/&gt; 
      &lt;/TaxIdentity&gt; 
      &lt;TaxIdentity&gt; 
       &lt;id&gt;42-123456&lt;/id&gt; 
      &lt;/TaxIdentity&gt; 
      &lt;Name&gt;ABC Company&lt;/Name&gt; 
      &lt;Number&gt;2230&lt;/Number&gt; 
     &lt;/Company&gt; 
    </xml> 
</theRootNode> 

У меня есть 2,0 таблицы стилей XSLT, который удаляет пространства имен и анализирует узел XML. В рамках одного и того же преобразования мне теперь нужно удалить любые узлы «TaxIdentity», которые имеют пустые значения в узле xml, который я только что проанализировал.

Текущие результаты:

<theRootNode> 
    <xml> 
     <Company> 
      <TaxIdentity> 
       <id/> 
      </TaxIdentity> 
      <TaxIdentity> 
       <id>42-123456</id> 
      </TaxIdentity> 
      <Name>ABC Company</Name> 
      <Number>2230</Number> 
     </Company> 
    </xml> 
</theRootNode> 

Желаемые результаты:

<theRootNode> 
    <xml> 
     <Company> 
      <TaxIdentity> 
       <id>42-123456</id> 
      </TaxIdentity> 
      <Name>ABC Company</Name> 
      <Number>2230</Number> 
     </Company> 
    </xml> 
</theRootNode> 

Мой XSLT ниже. Обратите внимание, что моя мысль заключалась в том, чтобы перенести исходные результаты в переменную, используя as = "element() или использовать parse-xml (версия 3), но я не могу удалить удаленные узлы. Обратите внимание, что моя цель НЕ удалить все пустые элементы или узлы ... только те, названные TaxIdentiy. Какой подход следует принять? решения? Мне действительно нужно все это в то же преобразование. Спасибо.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no" omit-xml-declaration="yes"/> 
    <!-- Copy elements without copying their namespace declarations --> 
    <xsl:template match="*[not(local-name() = 'xml')]" name="identity"> 
     <xsl:element name="{name()}" namespace=""> 
      <xsl:apply-templates select="node() | @*"/> 
     </xsl:element> 
    </xsl:template> 
    <!-- Copy content as is with lower priority --> 
    <xsl:template match="node() | @*" priority="-2"> 
     <xsl:copy> 
      <xsl:apply-templates select="node() | @*"/> 
     </xsl:copy> 
    </xsl:template> 
    <!-- turn xml node content back into xml --> 
    <xsl:template match="*[local-name() = 'xml']"> 
     <xsl:element name="xml" inherit-namespaces="no" namespace=""> 
      <xsl:value-of select="." disable-output-escaping='yes'/> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

ответ

1

Вот мой XSLT 3.0 предложение, которое просто разбирает XML с parse-xml, а затем применить-шаблоны для разбираемых узлов с шаблоном удаления в TaxIdentity со всеми пустыми дочерними элементами:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
    xmlns:is="http://myNamespace" 
    exclude-result-prefixes="is xs math" 
    version="3.0"> 

    <xsl:mode on-no-match="shallow-copy"/> 

    <xsl:template match="is:*"> 
     <xsl:element name="{local-name()}"> 
      <xsl:apply-templates select="@* , node()"></xsl:apply-templates> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="is:xml"> 
     <xsl:element name="{local-name()}"> 
      <xsl:apply-templates select="parse-xml(.)/node()"/> 
     </xsl:element> 
    </xsl:template> 

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

</xsl:stylesheet> 
+0

Спасибо Это приста ks, я все еще расшифровываю методы. – johkar

+0

'' заменяет в XSLT 3.0 ваш второй шаблон. И пустой '' является стандартным способом избежать копирования узлов, которые вы не хотите копировать. –