【问题标题】:XSLT: Copy Element with its surrounding Elements (Recursive Loop Error)XSLT:复制元素及其周围元素(递归循环错误)
【发布时间】:2019-11-14 14:25:29
【问题描述】:

我正在努力寻找解决这个问题的方法,因为我最终陷入了递归循环。

XML 源示例:

<runtime xmlns="http://xxx/v1"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="xxx.xsd">
    <messages>
        <message>
            <severity>debug</severity>
            <source>Client</source>
            <subject>Subject</subject>
            <body>Body</body>
        </message>
    </messages>

而且我需要将 Messages 元素放入 body 元素中

  <runtime xmlns="http://xxx/v1"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="xxx.xsd">
        <messages>
            <message>
                <severity>debug</severity>
                <source>Client</source>
                <subject>Subject</subject>

                <body>

                <messages>
                    <message>
                        <severity>debug</severity>
                        <source>Client</source>
                        <subject>Subject</subject>
                        <body>Body</body>
                </message>
                </messages>

               </body>

            </message>
        </messages>

如果不以循环错误告终,我无法提出可行的解决方案。任何帮助。

【问题讨论】:

    标签: xml xslt xpath xsd transformation


    【解决方案1】:

    您必须运行除&lt;body&gt; 元素之外的复制模板。对于这个特殊标签,制作另一个复制模板,并命名为从新开始驱动转换,并按顺序使用另一个路径来避免循环。

    正文的经典副本模板执行

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

    对于body元素,通过分配另一个路径(带模式)从头开始复制

     <xsl:template match="*[local-name()='body']">
        <xsl:copy>
            <xsl:apply-templates select="/*:runtime/*:messages" mode='embedded'/>
        </xsl:copy>
    </xsl:template>
    

    并使用另一个复制模板将标签复制到正文元素中

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

    结果:

    <?xml version="1.0" encoding="UTF-8"?>
    <runtime xmlns="http://xxx/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="xxx.xsd">
        <messages>
            <message>
                <severity>debug</severity>
                <source>Client</source>
                <subject>Subject</subject>
                <body>
                    <messages>
                        <message>
                            <severity>debug</severity>
                            <source>Client</source>
                            <subject>Subject</subject>
                            <body>Body</body>
                        </message>
                    </messages>
                </body>
            </message>
        </messages>
    </runtime>
    

    【讨论】:

      【解决方案2】:

      这是您可以查看的一种方式:

      XSLT 1.0

      <xsl:stylesheet version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:v1="http://xxx/v1">
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
      
      <!-- identity transform -->
      <xsl:template match="@*|node()">
          <xsl:copy>
              <xsl:apply-templates select="@*|node()"/>
          </xsl:copy>
      </xsl:template>
      
      <xsl:template match="v1:body">
          <xsl:copy>
              <xsl:copy-of select="../.."/>
          </xsl:copy>
      </xsl:template>
      
      </xsl:stylesheet>
      

      作为一项智力练习,在 XSLT 2.0 中您可以:

      <xsl:stylesheet version="2.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xpath-default-namespace="http://xxx/v1">
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
      
      <!-- identity transform -->
      <xsl:template match="@*|node()" mode="#all">
          <xsl:copy>
              <xsl:apply-templates select="@*|node()" mode="#current"/>
          </xsl:copy>
      </xsl:template>
      
      <xsl:template match="body">
          <xsl:copy>
              <xsl:apply-templates select="../.." mode="copy"/>
          </xsl:copy>
      </xsl:template>
      
      <xsl:template match="body" mode="copy">
          <xsl:copy>
              <xsl:apply-templates/>
          </xsl:copy>
      </xsl:template>
      
      </xsl:stylesheet>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-26
        • 2016-11-23
        • 2017-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-08
        相关资源
        最近更新 更多