Выберите родительский узел без дочернего узла. XSLT - PullRequest
0 голосов
/ 16 февраля 2020

Я хотел бы выбрать родительский узел без дочернего узла.

Пример:

<Shop>
    <Product>
       <ProductId>1</ProductId>
       <Description>ProductList</Description> 
       <Milk>
         <MilkId></MilkId>
       </Milk>
    </Product>
</Shop>

Желаемый вывод:

<Shop>
    <Product>
       <ProductId>1</ProductId>
       <Description>ProductList</Description> 
    </Product>
</Shop>

Я пробовал ниже XSLT, но это не удалось чтобы вернуть правильный результат:

<xsl:copy-of select="//Product/not[Milk]"/>

Спасибо за любую помощь.

Обновление:

XSLT:

<xsl:copy-of select="Product/*[not(self::Milk)]" />

Возвраты:

<ProductId>1</ProductId>

Мне нужна структура ниже, чтобы быть возвращенной:

<Shop>
        <Product>
           <ProductId>1</ProductId>
           <Description>ProductList</Description> 
        </Product>
    </Shop>

1 Ответ

0 голосов
/ 16 февраля 2020

Вы можете использовать вариант шаблона Identity :

<!-- Identity template variant -->
<xsl:template match="node()|@*">
    <xsl:copy>
         <xsl:apply-templates select="node()[local-name()!='Milk']|@*" />
    </xsl:copy>
</xsl:template>

или, как более XSLT-2.0, предложенный в комментариях

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

Он копирует все узлы, кроме названных Milk и его дочерних элементов.


Если вы хотите применить это только к Product узлам, вы также должны использовать шаблон Identity и измените правило сопоставления на

<xsl:template match="Product">...

Решением, использующим только xsl:copy-of, может быть копирование элемента Product, а затем копирование всех его дочерних элементов (кроме Milk) ) с

<xsl:copy-of select="Product/*[not(self::Milk)]" />

Или в целом шаблоне XSLT-2.0

<xsl:template match="//Product">
    <xsl:copy>
      <xsl:copy-of select="* except Milk" />
    </xsl:copy>
</xsl:template>

Вся таблица стилей XSLT-1.0 может выглядеть как

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

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

    <xsl:template match="Product">
        <xsl:copy>
          <xsl:copy-of select="*[not(self::Milk)]" />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Его вывод:

<?xml version="1.0"?>
<Shop>
    <Product>
        <ProductId>1</ProductId>
        <Description>ProductList</Description>
    </Product>
</Shop>
...