XSL удаляет пустые дочерние узлы, но если нет дочерних, создайте их - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь отформатировать следующий XML, удаляя все пустые узлы «параметров» (без дочернего узла «ключ»), но если все они пусты, мне нужно создать один. Допустим, мне нужно иметь хотя бы один узел «параметров» для каждого «покрытия»

Ввод XML:

<root>
   <coverages>
      <parameters> 
        <enumValues/>
      </parameters>
      <parameters>
        <enumValues/>
      </parameters>
      <parameters>
        <enumValues/>
      </parameters>
      <id>P01</id>
      <name>P01 coverage</name>
      <parameters>
        <key>key1</key>
        <name>Key1 Name</name>
        <defaultValue>1</defaultValue>
      </parameters>
   </coverages>
   <coverages>
      <parameters>
        <enumValues/>
      </parameters>
      <parameters>
        <enumValues/>
      </parameters>
      <parameters>
        <enumValues/>
      </parameters>
      <id>P03</id>
      <name>P03 coverage</name>
   </coverages>
</root>

Ожидаемый результат:

<root>
    <coverages>
        <id>P01</id>
        <name>P01 coverage</name>
        <parameters>
            <key>key1</key>
            <name>Key1 Name</name>
            <defaultValue>1</defaultValue>
        </parameters>
    </coverages>
    <coverages>
        <id>P03</id>
        <name>P03 coverage</name>
        <parameters>
            <key>key2</key>
            <name>Key2 Name</name>
            <defaultValue>2</defaultValue>
        </parameters>
    </coverages>
</root>

Я на самом деле застрял с преобразованием для применения, потому что я могу легко удалить пустые узлы, но тогда у меня нет понятия, как добавить один

Я использую следующий шаблон:

<xsl:template match="coverages/parameters[not(descendant::key[not(*)][normalize-space()])]" />

но это только удаляет пустые

1 Ответ

0 голосов
/ 03 апреля 2020

Попробуйте что-то вроде:

XSLT 1.0

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

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

<xsl:template match="parameters[not(key)]"/>

<xsl:template match="coverages[not(parameters/key)]">
    <xsl:copy>
        <xsl:apply-templates/>
        <parameters>
            <key>some value</key>
            <name>some value</name>
            <defaultValue>some value</defaultValue>
        </parameters>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
...