Использование XSLT для создания DITA в XML выводит несколько один и тот же элемент попадает под дочерний элемент к родительскому элементу

Во время преобразования входного файла DITA в выходной XML несколько одинаковых элементов, таких как <p class="- topic/p " outputclass="MLU_Intro">один родительский тег, преобразуются в несколько одинаковых тегов.

I’M new to XSLT, Please anyone guide me to resolve above issue.

Мой входной XML-файл:

<!DOCTYPE topic PUBLIC "urn:pubid:com.staywell.doctypes:doctypes:dita:topic" "topic.dtd">
<topic   class="- topic/topic " ditaarch_DITAArchVersion="1.2" domains="(topic hi-d) (topic indexing-d)(topic d4p_formatting-d)a(props d4p_renditionTarget)(topic d4p_math-d)(topic d4p_variables-d)(topic d4p_verse-d)(topic learningInteractionBase2-d learning2-d+learning-d)(topic learningBase+learningInteractionBase-d)(topic learningInteractionBase-d)(topic learningInteractionBase2-d)(topic xml-d)a(base rsuiteIdAtt)(topic sdClassification-d)  " id="d43e3" outputclass="DOCTYPE-MLU" r_rsuiteId="6514" xml_lang="en-US">
  <title class="- topic/title " outputclass="MLU">All About the A1C</title>
  <body class="- topic/body ">
    <p class="- topic/p " outputclass="MLU_Code">TP_02A</p>
    <p class="- topic/p " outputclass="MLU_Type">Horizontal Click &amp; Learn</p>
  </body>
  <topic class="- topic/topic " ditaarch_DITAArchVersion="1.2" domains="(topic hi-d) (topic indexing-d)(topic d4p_formatting-d)a(props d4p_renditionTarget)(topic d4p_math-d)(topic d4p_variables-d)(topic d4p_verse-d)(topic learningInteractionBase2-d learning2-d+learning-d)(topic learningBase+learningInteractionBase-d)(topic learningInteractionBase-d)(topic learningInteractionBase2-d)(topic xml-d)a(base rsuiteIdAtt)(topic sdClassification-d)  " id="d43e15" outputclass="TOPIC-MLU-Header" r_rsuiteId="6515" xml_lang="en-US">
    <title class="- topic/title " outputclass="MLU-Header">Header</title>
    <body class="- topic/body ">
      <p class="- topic/p " outputclass="MLU_Category">Management</p>
      <p class="- topic/p " outputclass="MLU_Banner_Display">Yes</p>
      **
      <p class="- topic/p " outputclass="MLU_Intro">It’s great that.</p>
      <p class="- topic/p " outputclass="MLU_Intro">
        <ph class="- topic/ph " outputclass="Bold">Why the A1C</ph>
      </p>
      <p class="- topic/p " outputclass="MLU_Intro">An A1C test.</p>
      <p class="- topic/p " outputclass="MLU_Intro">
        <ph class="- topic/ph " outputclass="Bold">What to</ph>
        <ph class="- topic/ph " outputclass="Bold">Results</ph>
      </p>
      <p class="- topic/p " outputclass="MLU_Intro">An A1C test result.</p>
      **
      <p class="- topic/p " outputclass="MLU_Directions">CLICK ON EACH ICON TO LEARN MORE.</p>
    </body>
  </topic>
</topic>

XSL, который я использовал:

<xsl:stylesheet  version="2.0">
  <xsl:output method="xml" encoding="UTF-8" doctype-system="../DTDs/MLU.dtd" indent="yes" />
  <xsl:strip-space elements="*" />

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

  <xsl:template match="topic[@outputclass = 'DOCTYPE-MLU']">
    <MLU>
      <clickLearnHorizontal>
        <xsl:apply-templates />
      </clickLearnHorizontal>
    </MLU>
  </xsl:template>

  <xsl:template match="topic[@outputclass = 'TOPIC-MLU-Header']">
    <header>
      <trackingSettings>
        <urlcode>
          <xsl:value-of select="//p[@outputclass = 'MLU_Code']" />
        </urlcode>
        <apiurl>http://mlucenter.com/like/api</apiurl>
      </trackingSettings>
      <page>
        <xsl:value-of select="text()" />
      </page>
      <banner>
        <enabled>true</enabled>
        <text>
          <xsl:value-of select="//title[@outputclass = 'MLU']" />
        </text>
      </banner>
      <xsl:apply-templates />
    </header>
  </xsl:template>

  <xsl:template match="body">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="p[@outputclass = 'MLU_Code']" />
  <xsl:template match="title[@outputclass = 'MLU']" />
  <xsl:template match="title[@outputclass = 'MLU-Header']" />
  <xsl:template match="p[@outputclass = 'MLU_Condition']" />
  <xsl:template match="p[@outputclass = 'MLU_Type']" />
  <xsl:template match="p[@outputclass = 'MLU_Category']" />
  <xsl:template match="p[@outputclass = 'MLU_Banner_Display']" />
  <xsl:template match="p[@outputclass = 'MLU_Banner_Color']" />

  <xsl:template match="p">
    <introText>
      <text>
        <xsl:for-each select="p[@outputclass = 'MLU_Intro']">
          <p>
            <xsl:apply-templates />
          </p>
        </xsl:for-each>
      </text>
    </introText>
  </xsl:template>

  <!--<xsl:template match="p[@outputclass = 'MLU_Intro']"> </xsl:template>-->

  <xsl:template match="p[@outputclass = 'MLU_Directions']">
    <directionText>
      <text>
        <xsl:value-of select="//p[@outputclass = 'MLU_Directions']" />
      </text>
    </directionText>
  </xsl:template>

  <xsl:template match="title[@outputclass = 'MLU-Body']" />
  <xsl:template match="title" />
  <xsl:template match="ph">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="p[@outputclass = 'MLU_Item_Button']" />
  <xsl:template match="p[@outputclass = 'MLU_Item_Title_Position']" />
  <xsl:template match="bodydiv[@outputclass = 'Item_Defaults']" />

  <xsl:template match="bodydiv">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="p">
    <p>
      <xsl:apply-templates />
    </p>
  </xsl:template>

  <!--
  <xsl:template match="p[@outputclass = 'MLU_Intro']">
    <p>
    <xsl:apply-templates/>
    </p>
  </xsl:template>
  -->

  <xsl:template match="image" />
  <xsl:template match="@MLU_Banner_Display" />
  <xsl:template match="@class">
    <!--<xsl:apply-templates/>-->
  </xsl:template>

  <xsl:template match="ul">
    <ul>
      <xsl:apply-templates />
    </ul>
  </xsl:template>

  <xsl:template match="ol">
    <ol>
      <xsl:apply-templates />
    </ol>
  </xsl:template>

  <xsl:template match="li">
    <li>
      <xsl:apply-templates />
    </li>
  </xsl:template>

  <xsl:template match="ph[@outputclass = 'Bold']">
    <strong>
      <xsl:apply-templates />
    </strong>
  </xsl:template>
</xsl:stylesheet>

Выходной XML, который я получил как:

<!DOCTYPE MLU
  SYSTEM "../DTDs/MLU.dtd">
<MLU>
  <clickLearnHorizontal>
    <header>
      <trackingSettings>
        <urlcode>TP_02A</urlcode>
        <apiurl>http://mlucenter.com/like/api</apiurl>
      </trackingSettings>
      <page />
      <banner>
        <enabled>true</enabled>
        <text>All About the A1C</text>
      </banner>
      **
      <p>It’s great.</p>
      <p>
        <strong>Why the A1C</strong>
      </p>
      <p>An A1C test.</p>
      <p>
        <strong>What to Expect</strong>
        <strong>Results</strong>
      </p>
      <p>An A1C test.</p>
      **
      <directionText>
        <text>CLICK ON EACH ICON TO LEARN MORE.</text>
      </directionText>
    </header>
  </clickLearnHorizontal>
</MLU>

Но я ожидал выхода как:

<MLU>
  <clickLearnHorizontal>
    <header>
      <trackingSettings>
        <urlcode>TP_02A</urlcode>
        <apiurl>http://mlucenter.com/like/api</apiurl>
      </trackingSettings>
      <page />
      <banner>
        <enabled>true</enabled>
        <text>All About the A1C</text>
      </banner>
      **
      <introText>
        <text>
          <p>It’s great.</p>
          <p>
            <strong>Why the A1C</strong>
          </p>
          <p>An A1C test.</p>
          <p>
            <strong>What to Expect</strong>
            <strong>Results</strong>
          </p>
          <p>An A1C test.</p>
        </text>
      </introText>
      **
      <directionText>
        <text>CLICK ON EACH ICON TO LEARN MORE.</text>
      </directionText>
    </header>
  </clickLearnHorizontal>
</MLU>

2 ответа

  1. Вы можете использовать for-each-group group-adjacentследующее:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0" >
        <xsl:output method="xml" encoding="UTF-8" doctype-system="../DTDs/MLU.dtd" indent="yes"/>
        <xsl:strip-space elements="*"/>
        <xsl:template match="node() | @*">
            <xsl:copy>
                <xsl:apply-templates select="node() | @*"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="topic[@outputclass = 'DOCTYPE-MLU']">
            <MLU>
                <clickLearnHorizontal>
                    <xsl:apply-templates/>
                </clickLearnHorizontal>
            </MLU>
        </xsl:template>
        <xsl:template match="topic[@outputclass = 'TOPIC-MLU-Header']">
            <header>
                <trackingSettings>
                    <urlcode>
                        <xsl:value-of select="//p[@outputclass = 'MLU_Code']"/>
                    </urlcode>
                    <apiurl>http://mlucenter.com/like/api</apiurl>
                </trackingSettings>
                <page><xsl:value-of select="text()" /></page>
                <banner>
                    <enabled>true</enabled>
                    <text>
                        <xsl:value-of select="//title[@outputclass = 'MLU']"/>
                    </text>
                </banner>
                <xsl:apply-templates/>
            </header>
        </xsl:template>
        <xsl:template match="body">
            <xsl:for-each-group select="*" group-adjacent="boolean(self::p[@outputclass = 'MLU_Intro'])">
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                        <introText>
                            <text>
                                <xsl:apply-templates select="current-group()"/>
                            </text>
                        </introText>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:template>
        <xsl:template match="p[@outputclass = 'MLU_Code']"> </xsl:template>
        <xsl:template match="title[@outputclass = 'MLU']"> </xsl:template>
        <xsl:template match="title[@outputclass = 'MLU-Header']"> </xsl:template>
        <xsl:template match="p[@outputclass = 'MLU_Condition']"> </xsl:template>
        <xsl:template match="p[@outputclass = 'MLU_Type']"> </xsl:template>
        <xsl:template match="p[@outputclass = 'MLU_Category']"> </xsl:template>
        <xsl:template match="p[@outputclass = 'MLU_Banner_Display']"> </xsl:template>
        <xsl:template match="p[@outputclass = 'MLU_Banner_Color']"> </xsl:template>
    
        <xsl:template match="p[@outputclass = 'MLU_Intro']">
            <p><xsl:apply-templates/></p>
        </xsl:template>
    
        <xsl:template match="p[@outputclass = 'MLU_Directions']">
            <directionText>
                <text>
                    <xsl:value-of select="//p[@outputclass = 'MLU_Directions']"/>
                </text>
            </directionText>
        </xsl:template>
        <xsl:template match="title[@outputclass = 'MLU-Body']"> </xsl:template>
        <xsl:template match="title"> </xsl:template>
        <xsl:template match="ph">
            <xsl:apply-templates/>
        </xsl:template>
        <xsl:template match="p[@outputclass = 'MLU_Item_Button']"> </xsl:template>
        <xsl:template match="p[@outputclass = 'MLU_Item_Title_Position']"> </xsl:template>
        <xsl:template match="bodydiv[@outputclass = 'Item_Defaults']"> </xsl:template>
        <xsl:template match="bodydiv">
            <xsl:apply-templates/>
        </xsl:template>
        <xsl:template match="p">
            <p>
                <xsl:apply-templates/>
            </p>
        </xsl:template>
    
        <xsl:template match="image"></xsl:template>
        <xsl:template match="@MLU_Banner_Display"> </xsl:template>
        <xsl:template match="@class">
            <!--<xsl:apply-templates/>-->
        </xsl:template>
        <xsl:template match="ul">
            <ul>
                <xsl:apply-templates/>
            </ul>
        </xsl:template>
        <xsl:template match="ol">
            <ol>
                <xsl:apply-templates/>
            </ol>
        </xsl:template>
        <xsl:template match="li">
            <li>
                <xsl:apply-templates/>
            </li>
        </xsl:template>
        <xsl:template match="ph[@outputclass = 'Bold']">
            <strong>
                <xsl:apply-templates/>
            </strong>
        </xsl:template>
    </xsl:stylesheet>
    
  2. В настоящее время у вас есть два шаблона, которые match="p". Второй используется.

    В XSLT, так же как и в CSS, если два правила могут соответствовать данному узлу, правило, определенное last wins.

    Шаги для решения:

    • Либо удалите второй шаблон, либо
    • изменение порядка шаблонов или
    • пусть один из них соответствует чему-то более конкретному, чем p