基于特定文本拆分XML节点

时间:2014-11-20 17:05:39

标签: xslt

请根据特定注释文本(<! - Break - >)建议如何拆分xml节点。我尝试使用 xsl:text disable-output-escaping 格式来放置所需的结束标记和开始标记(元素)。

  • 我的代码是静态的,如何制作适用于评论文本的任何数量的祖先的动态代码,即,如果祖先计数' n ',然后从 n到1 如何使用调用模板方法。
  • 提供了一些空节点,它们不是内容的祖先,如何避免这些

我从我们的网站上提到了一些建议,但发现很难理解逻辑。请建议。 (XSLT 2版)

XSLT:

<root>
    <a>
        <b>The text1
            <c>
                <d>The text2</d><d>The text3</d><!--Break--><d>The text4</d>
                <e>The text5<!--Break--></e>
            </c>
            <f>The text6</f>
        </b>
    </a>
</root>

XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:template match="@*|node()">
     <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
   </xsl:template>

   <xsl:template match="//comment()[contains(., 'Break')]">
       <xsl:variable name="varAncestorCount" select="count(ancestor::*)"/>
       <xsl:choose>
           <xsl:when test="$varAncestorCount = 4">
               <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="ancestor::*[1]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                   <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="ancestor::*[2]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                       <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="ancestor::*[3]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                           <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="ancestor::*[4]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                               <xsl:comment><xsl:value-of select="."/></xsl:comment>
                           <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="ancestor::*[4]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>    
                       <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="ancestor::*[3]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                   <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="ancestor::*[2]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
               <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="ancestor::*[1]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
           </xsl:when>
           <xsl:when test="$varAncestorCount = 5">
               <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="ancestor::*[1]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                   <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="ancestor::*[2]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                       <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="ancestor::*[3]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                           <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="ancestor::*[4]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                               <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="ancestor::*[5]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                                   <xsl:comment><xsl:value-of select="."/></xsl:comment>
                               <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="ancestor::*[5]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>    
                           <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="ancestor::*[4]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>    
                       <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="ancestor::*[3]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
                   <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="ancestor::*[2]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
               <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="ancestor::*[1]/name()"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
           </xsl:when>
       </xsl:choose>

   </xsl:template>

 </xsl:stylesheet>

期望的输出:

<root>
    <a>
        <b>The text1
            <c>
                <d>The text2</d>
                <d>The text3</d>
            </c>
        </b>
    </a>
</root>
<!--Break-->
<root>
    <a>
        <b>
            <c>
                <d>The text4</d>
                <e>The text5</e>
            </c>
        </b>
    </a>
</root>
<!--Break-->
<root>
    <a>
        <b>
            <f>The text6</f>
        </b>
    </a>
</root>

1 个答案:

答案 0 :(得分:4)

[呻吟]你在哪里找到这些&#34;有趣的&#34;任务?

您永远不应要求使用转义文本手动构建XML节点。

尝试以下样式表。它可能更精简,但我相信它解决了这里的主要问题:

XSLT 2.0

<xsl:stylesheet version="2.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="*"/>

<xsl:variable name="root" select="/*" />

<xsl:template match="/">
    <super-root>
        <xsl:for-each select="0 to count(//comment()[.='Break'])">
            <xsl:apply-templates select="$root">
                <xsl:with-param name="i" select="." tunnel="yes"/>
            </xsl:apply-templates>
            <xsl:if test="position()!=last()">
                <xsl:comment>Break</xsl:comment>
            </xsl:if>
        </xsl:for-each >
    </super-root>
</xsl:template>

<xsl:template match="@*|node()">
    <xsl:param name="i" tunnel="yes"/>
        <xsl:if test="descendant-or-self::text()[count(preceding::comment()[.='Break'])=$i]">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:if>
</xsl:template>

</xsl:stylesheet>

<强>结果

<?xml version="1.0" encoding="UTF-8"?>
<super-root>
   <root>
      <a>
         <b>The text1
            <c>
               <d>The text2</d>
               <d>The text3</d>
            </c>
         </b>
      </a>
   </root>
   <!--Break-->
   <root>
      <a>
         <b>
            <c>
               <d>The text4</d>
               <e>The text5</e>
            </c>
         </b>
      </a>
   </root>
   <!--Break-->
   <root>
      <a>
         <b>
            <f>The text6</f>
         </b>
      </a>
   </root>
</super-root>