удалить узел на основе дочернего узла - PullRequest
0 голосов
/ 17 мая 2018

В настоящее время мой XSL работает для удаления узлов с определенными атрибутами (спасибо stackoverflow). Учитывая следующее xml

<Document>
  <Node1>
   <Node2>
    <Node3 etv:severity="ok"> stuff </Node3>
    <Node3 etv:severity="ok"> stuff </Node3>
    <Node3 etv:severity="skip"> stuff </Node3>
  </Node2>
  <Node2>
    <Node3 etv:severity="ok"> stuff </Node3>
    <Node3 etv:severity="ok"> stuff </Node3>
    <Node3 etv:severity="skip"> stuff </Node3>
  </Node2>
  <Node2>
    <Node3 etv:severity="skip"> stuff </Node3>
    <Node3 etv:severity="skip"> stuff </Node3>
    <Node3 etv:severity="skip"> stuff </Node3>
  </Node2>
 </Node1>
</Document>

с этим xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:etv="urn:com.etv/etv"
    xmlns:iso="urn:iso">

    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="/iso:Document/iso:Node1/iso:Node2/iso:Node3[(@etv:severity='skip')]" />
</xsl:stylesheet>

Обратите внимание, что в 3-м экземпляре Node2 все Node3 по ошибке. Я хотел бы также удалить все Node 2 в этом случае. это можно сделать за 1 преобразование?

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

<Document>
  <Node1>
   <Node2>
    <Node3 etv:severity="ok"> stuff </Node3>
    <Node3 etv:severity="ok"> stuff </Node3>
  </Node2>
  <Node2>
    <Node3 etv:severity="ok"> stuff </Node3>
    <Node3 etv:severity="ok"> stuff </Node3>
  </Node2>
  <Node2>
  </Node2>
 </Node1>
</Document>

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Предположим, у вас есть этот упрощенный входной файл (у вас слишком много пространств имен, действительно ли они вам нужны? Если необходимо, тогда я позволю вам соответствующим образом исправить таблицу стилей)

ВХОД:

$ more document.xml 
<Document>
  <Node1>
   <Node2>
    <Node3 severity="ok"> stuff </Node3>
    <Node3 severity="ok"> stuff </Node3>
    <Node3 severity="skip"> stuff </Node3>
  </Node2>
  <Node2>
    <Node3 severity="ok"> stuff </Node3>
    <Node3 severity="ok"> stuff </Node3>
    <Node3 severity="skip"> stuff </Node3>
  </Node2>
  <Node2>
    <Node3 severity="skip"> stuff </Node3>
    <Node3 severity="skip"> stuff </Node3>
    <Node3 severity="skip"> stuff </Node3>
  </Node2>
 </Node1>
</Document>

STYLESHEET:

$ more document.xslt 
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:etv="urn:com.etv/etv" xmlns:iso="urn:iso" exclude-result-prefixes="etv iso">

    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="//Node2">
        <xsl:choose>
                <xsl:when test="count(./Node3[@severity='ok']) = 0">
                         <Node2></Node2><!-- you can remove this line if you do not want to have Node2 produced-->
                </xsl:when>
                <xsl:otherwise>
                        <Node2><xsl:apply-templates select="@*|node()" /></Node2>
                </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="//Node3[@severity='skip']"/>
</xsl:stylesheet>

РЕЗУЛЬТАТ:

$ java -jar saxon9he.jar -s:document.xml -xsl:document.xslt
<?xml version="1.0" encoding="UTF-8"?>
<Document>
   <Node1>
      <Node2>
         <Node3 severity="ok"> stuff </Node3>
         <Node3 severity="ok"> stuff </Node3>
      </Node2>
      <Node2>
         <Node3 severity="ok"> stuff </Node3>
         <Node3 severity="ok"> stuff </Node3>
      </Node2>
      <Node2/>
   </Node1>
</Document>

Вы можете полностью удалить пустую Node2, прокомментировав строку в when в таблице стилей. Удачи

0 голосов
/ 17 мая 2018

Предполагая, что входной XML с объявленными правильными пространствами имен, вы можете добавить этот шаблон:

<xsl:template match="iso:Node2[not(*/@etv:severity!='skip')]"/>

См. http://xsltfiddle.liberty -development.net / 3NzcBsX .

...