Удалить родительский узел, если childnode имеет определенный атрибут - PullRequest
0 голосов
/ 11 июня 2019

Это связано с моим предыдущим вопросом, но теперь цель другая.Рассматривая ниже XML-файл:

<project>
    <UserProjAttr>G</UserProjAttr>
</project>
<mainpart>
    <proxy>
        <singlepart>
            <part>
                <coating>SP</coating>
            </part>
        </singlepart>
        <singlepart>
            <part>
                <coating>G</coating>
            </part>
        </singlepart>
        <singlepart>
            <part>
                <coating>G</coating>
            </part>
        </singlepart>
    </proxy>
</mainpart>   

Номер отдельного узла является динамическим;но мне нужно проверить, что все значения // mainpart / proxy / singlepart / part / coating совпадают со значением // project / UserProjAttr, если есть разница, весь узел mainpart можно пропустить для копирования.

Ниже приведен мой код, но, конечно, это проблематично из-за моей неопытности с xslt.

<xsl:variable name="finish" select="/project/UserProjAttr"/>
<xsl:template match="proxy">
    <xsl:choose>
    <xsl:when test="$currfinish = 'false'">
    </xsl:when>
        <xsl:otherwise>
            <xsl:copy>
                <xsl:apply-templates select="@*|node()" />
            </xsl:copy>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:variable name="currfinish" >
    <xsl:for-each select="@*|singlepart" >
        <xsl:if test="not(@*|singlepart[part/coating/@key = $finish])" >
            <xsl:value-of select="false()" />
        </xsl:if>
    </xsl:for-each>
</xsl:variable>

1 Ответ

0 голосов
/ 11 июня 2019

Если вы просто планируете удалить узлы и оставить другие узлы без изменений, всегда полезно начать с шаблона идентификации, так как он заботится о копировании того, что вам нужно.

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

Это означает, что вам нужен шаблон, чтобы игнорировать mainpart, если все дочерние элементы coating соответствуют UserProjAttr. Вернее, если нет потомка coating, который не соответствует UserProjAttr

<xsl:template match="mainpart[not(proxy/singlepart/part/coating != //project/UserProjAttr)]" />

Попробуйте это XSLT

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

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

  <xsl:template match="mainpart[not(proxy/singlepart/part/coating != //project/UserProjAttr)]" />
</xsl:stylesheet>

Обратите внимание: если вы используете XSLT 2.0, вы можете использовать переменную в шаблоне, если считаете, что она делает его более читабельным

<xsl:variable name="finish" select="//project/UserProjAttr"/>

<xsl:template match="mainpart[not(proxy/singlepart/part/coating != $finish)]" />

А в XSLT 3.0 шаблон идентификации можно заменить одной строкой ...

<xsl:mode on-no-match="shallow-copy"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...