0

我正在尝试使用 XSLT 2.0 对 XML 进行非规范化。

下面是 XML 和相同的预期输出。如果有人可以提供 XSLT 来实现这一点,将会有很大的帮助。非规范化应该只适用于以“Change”开头的标签,而不适用于其他标签。其他标签应保持原样。

示例输入 XML

<p> This is normal text

            <changebold>This is new line</changebold>

            My Name is

            <table>

                        <tr>

                                    <td>FirstName</td>

                                    <td>LastName</td>

                                    <td>Testing for <changebold>Bold <changeitalic>Italic <changeunderline>UnderLine</changeunderline>

                                                            </changeitalic>

                                                </changebold>

                                    </td>

                        </tr>

            </table>

            <changebold>The Test <changeitalic>of Chemistry<changeunderline>is passed</changeunderline>

                        </changeitalic> and for biology <changeunderline>the result</changeunderline> is unknown <changeunderline> and under process.</changeunderline>

                        <changeitalic>The result</changeitalic> of same<changeunderline>will be</changeunderline> displayed on  <changeitalic>noticeboard soon.</changeitalic>

            </changebold>

            <table>table heading <tr>Row <td>Cell1</td>Row End</tr>Table Heading end. </table>

</p>

上述 XML 的预期输出

<p> This is normal text

            <changebold>This is new line</changebold>

            My Name is

            <table>

                        <tr>

                                    <td>FirstName</td>

                                    <td>LastName</td>

                                    <td>Testing for <changebold>Bold </changebold>

                                                <changebold>

                                                            <changeitalic>Italic</changeitalic>

                                                </changebold>

                                                <changebold>

                                                            <changeitalic>

                                                                        <changeunderline>UnderLine</changeunderline>

                                                            </changeitalic>

                                                </changebold>

                                    </td>

                        </tr>

            </table>

            <changebold>The Test </changebold>

            <changebold>

                        <changeitalic>of Chemistry</changeitalic>

            </changebold>

            <changebold>

                        <changeitalic>

                                    <changeunderline>is passed</changeunderline>

                        </changeitalic>

            </changebold>

            <changebold> and for biology </changebold>

            <changebold>

                        <changeunderline>the result</changeunderline>

            </changebold>

            <changebold> is unknown </changebold>

            <changebold>

                        <changeunderline> and under process.</changeunderline>

            </changebold>

            <changebold>

                        <changeitalic>The result</changeitalic>

            </changebold>

            <changebold> of same</changebold>

            <changebold>

                        <changeunderline>will be</changeunderline>

            </changebold>

            <changebold> displayed on  </changebold>

            <changebold>

                        <changeitalic>noticeboard soon.</changeitalic>

            </changebold>

            <table>table heading <tr>Row <td>Cell1</td>Row End</tr>Table Heading end. </table>

</p>
4

1 回答 1

0

看看这个能够产生所需输出的 ​​XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="(node() | @*)"/>
    </xsl:copy>
  </xsl:template>

  <!--To check if element starts with change and has some child element with the name of change -->
  <xsl:template
    match="*[starts-with(name(self::*), 'change') and child::*[starts-with(name(self::*), 'change')]]">
    <xsl:call-template name="checkNode">
      <xsl:with-param name="element" select="self::*"/>
    </xsl:call-template>
  </xsl:template>

  <!-- This checkNode is producing almost 90% result but it fails when we have <changebold>Bold <changeitalic>Italic <changeunderline>UnderLine</changeunderline>
  it is producing result like:
  <changebold>
    <changeitalic>Italic </changeitalic>
      <changeitalic>
      <changeunderline>UnderLine</changeunderline>
      </changeitalic>
  </changebold>
  -->
  <xsl:template name="checkNode">
    <xsl:param name="element"/>
    <xsl:param name="nesting">
      <xsl:for-each select="$element/node()">
        <xsl:element name="{self::node()/parent::node()/name()}">
          <xsl:apply-templates select="."/>
        </xsl:element>
      </xsl:for-each>
    </xsl:param>
    <xsl:for-each select="$nesting/child::*">
      <xsl:choose>
        <xsl:when test="count(self::*/child::*) gt 1">
          <xsl:call-template name="getChild">
            <xsl:with-param name="element" select="self::*"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:copy-of select="."/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:template>

  <!-- Here, we are iterating again to get the desired result which was not done by previous 'checkNode' template-->
  <xsl:template name="getChild">
    <xsl:param name="element"/>
    <xsl:param name="start" select="xs:integer(1)"/>
    <xsl:param name="countChild" select="count($element/child::*)"/>
    <xsl:choose>
      <xsl:when test="$start le $countChild">
        <xsl:element name="{self::*/name()}">
          <xsl:copy-of select="child::*[$start]"/>
        </xsl:element>
        <xsl:call-template name="getChild">
          <xsl:with-param name="element" select="$element"/>
          <xsl:with-param name="countChild" select="$countChild"/>
          <xsl:with-param name="start" select="$start + 1"/>
        </xsl:call-template>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>
于 2013-04-23T12:57:39.117 回答