我如何使用键来转换它

发布于 2024-10-04 11:01:41 字数 2680 浏览 1 评论 0原文

我可以在不使用键的情况下编写一个非常糟糕的 xslt,但它非常慢且混乱。有谁知道我如何将以下 XML 文件干净地转换为预期结果?谢谢!

输入:

<testExecution>
    <test>
        <test.1/>
        <test.2/>
        <test.3/>
    </test>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <executor>
        <executor.1/>
        <executor.2/>
        <executor.3/>
    </executor>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <invoker>
        <invoker.1/>
        <invoker.2/>
        <invoker.3/>
    </invoker>
    <recipient>
        <recipient.1/>
        <recipient.2/>
        <recipient.3/>
    </recipient>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
</testExecution>

结果:

<testExecution>
    <test>
        <test.1/>
        <test.2/>
        <test.3/>
    </test>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <people>
        <importantPeople>
            <executor>
                <executor.1/>
                <executor.2/>
                <executor.3/>
            </executor>
            <comment>
                <comment.1/>
                <comment.2/>
                <comment.3/>
            </comment>
            <comment>
                <comment.1/>
                <comment.2/>
                <comment.3/>
            </comment>
        </importantPeople>
        <invoker>
            <invoker.1/>
            <invoker.2/>
            <invoker.3/>
        </invoker>
    </people>
    <recipient>
        <recipient.1/>
        <recipient.2/>
        <recipient.3/>
    </recipient>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
</testExecution>

I'm able to write a horribly bad xslt without using keys but it's quite slow and messy. Does anyone know how i would transform the following XML file into the expected result cleanly? Thanks!

input:

<testExecution>
    <test>
        <test.1/>
        <test.2/>
        <test.3/>
    </test>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <executor>
        <executor.1/>
        <executor.2/>
        <executor.3/>
    </executor>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <invoker>
        <invoker.1/>
        <invoker.2/>
        <invoker.3/>
    </invoker>
    <recipient>
        <recipient.1/>
        <recipient.2/>
        <recipient.3/>
    </recipient>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
</testExecution>

result:

<testExecution>
    <test>
        <test.1/>
        <test.2/>
        <test.3/>
    </test>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <people>
        <importantPeople>
            <executor>
                <executor.1/>
                <executor.2/>
                <executor.3/>
            </executor>
            <comment>
                <comment.1/>
                <comment.2/>
                <comment.3/>
            </comment>
            <comment>
                <comment.1/>
                <comment.2/>
                <comment.3/>
            </comment>
        </importantPeople>
        <invoker>
            <invoker.1/>
            <invoker.2/>
            <invoker.3/>
        </invoker>
    </people>
    <recipient>
        <recipient.1/>
        <recipient.2/>
        <recipient.3/>
    </recipient>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
</testExecution>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

国际总奸 2024-10-11 11:01:41

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kElementByTest" match="invoker|recipient"
             use="generate-id(preceding-sibling::test[1])"/>
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="executor">
        <xsl:variable name="vFollowing"
                      select="key('kElementByTest',
                                  generate-id(preceding-sibling::test[1]))"/>
        <people>
            <importantPeople>
                <xsl:call-template name="identity"/>
            </importantPeople>
            <xsl:apply-templates select="$vFollowing/self::invoker"
                                     mode="copy"/>
        </people>
        <xsl:apply-templates select="$vFollowing/self::recipient"
                             mode="copy"/>
    </xsl:template>
    <xsl:template match="invoker"/>
    <xsl:template match="recipient"/>
    <xsl:template match="node()" mode="copy">
        <xsl:call-template name="identity"/>
    </xsl:template>
</xsl:stylesheet>

输出:

<testExecution>
    <test>
        <test.1></test.1>
        <test.2></test.2>
        <test.3></test.3>
    </test>
    <comment>
        <comment.1></comment.1>
        <comment.2></comment.2>
        <comment.3></comment.3>
    </comment>
    <people>
        <importantPeople>
            <executor>
                <executor.1></executor.1>
                <executor.2></executor.2>
                <executor.3></executor.3>
            </executor>
            <comment>
                <comment.1></comment.1>
                <comment.2></comment.2>
                <comment.3></comment.3>
            </comment>
            <comment>
                <comment.1></comment.1>
                <comment.2></comment.2>
                <comment.3></comment.3>
            </comment>
        </importantPeople>
        <invoker>
            <invoker.1></invoker.1>
            <invoker.2></invoker.2>
            <invoker.3></invoker.3>
        </invoker>
    </people>
    <recipient>
        <recipient.1></recipient.1>
        <recipient.2></recipient.2>
        <recipient.3></recipient.3>
    </recipient>
    <comment>
        <comment.1></comment.1>
        <comment.2></comment.2>
        <comment.3></comment.3>
    </comment>
    <comment>
        <comment.1></comment.1>
        <comment.2></comment.2>
        <comment.3></comment.3>
    </comment>
</testExecution>

注意:细粒度遍历。 “仅用于此测试”的键如下。 “关闭此级别”的空模板。推送风格的模式“继续处理”。它可以是完整的“拉式”匹配“标记之前的上一个”。

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kElementByTest" match="invoker|recipient"
             use="generate-id(preceding-sibling::test[1])"/>
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="executor">
        <xsl:variable name="vFollowing"
                      select="key('kElementByTest',
                                  generate-id(preceding-sibling::test[1]))"/>
        <people>
            <importantPeople>
                <xsl:call-template name="identity"/>
            </importantPeople>
            <xsl:apply-templates select="$vFollowing/self::invoker"
                                     mode="copy"/>
        </people>
        <xsl:apply-templates select="$vFollowing/self::recipient"
                             mode="copy"/>
    </xsl:template>
    <xsl:template match="invoker"/>
    <xsl:template match="recipient"/>
    <xsl:template match="node()" mode="copy">
        <xsl:call-template name="identity"/>
    </xsl:template>
</xsl:stylesheet>

Output:

<testExecution>
    <test>
        <test.1></test.1>
        <test.2></test.2>
        <test.3></test.3>
    </test>
    <comment>
        <comment.1></comment.1>
        <comment.2></comment.2>
        <comment.3></comment.3>
    </comment>
    <people>
        <importantPeople>
            <executor>
                <executor.1></executor.1>
                <executor.2></executor.2>
                <executor.3></executor.3>
            </executor>
            <comment>
                <comment.1></comment.1>
                <comment.2></comment.2>
                <comment.3></comment.3>
            </comment>
            <comment>
                <comment.1></comment.1>
                <comment.2></comment.2>
                <comment.3></comment.3>
            </comment>
        </importantPeople>
        <invoker>
            <invoker.1></invoker.1>
            <invoker.2></invoker.2>
            <invoker.3></invoker.3>
        </invoker>
    </people>
    <recipient>
        <recipient.1></recipient.1>
        <recipient.2></recipient.2>
        <recipient.3></recipient.3>
    </recipient>
    <comment>
        <comment.1></comment.1>
        <comment.2></comment.2>
        <comment.3></comment.3>
    </comment>
    <comment>
        <comment.1></comment.1>
        <comment.2></comment.2>
        <comment.3></comment.3>
    </comment>
</testExecution>

Note: Fine grained traversal. Keys for "just for this test" followings. Empty templates for "close this level". Mode for push style "keep processing". It could be full "pull style" matching "the previus before the mark".

执妄 2024-10-11 11:01:41

此转换使用并覆盖身份规则。使用 key() 函数检索紧随 executor 的注释。紧随 executor 之后的 executorinvokercomment 会以名为 <代码>人。在通常的匿名模式中,它们与空模板匹配,以避免再次复制它们:

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

 <xsl:key name="kExecComments" match=
  "comment
          [preceding-sibling::*
              [not(self::comment)][1]
                       [self::executor]
          ]"
  use="generate-id(preceding-sibling::executor[1])"/>

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

 <xsl:template match="executor">
  <people>
    <importantPeople>
      <xsl:apply-templates mode="people"
        select=".|key('kExecComments', generate-id())"/>
    </importantPeople>
    <xsl:apply-templates mode="people" select=
    "following-sibling::invoker"/>
  </people>
 </xsl:template>

 <xsl:template match="executor|comment|invoker"
      mode="people">
    <xsl:call-template name="identity"/>
 </xsl:template>

 <xsl:template match=
  "invoker |
   comment
          [preceding-sibling::*
              [not(self::comment)][1]
                       [self::executor]
          ]"/>

</xsl:stylesheet>

应用于提供的 XML 文档时

<testExecution>
    <test>
        <test.1/>
        <test.2/>
        <test.3/>
    </test>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <executor>
        <executor.1/>
        <executor.2/>
        <executor.3/>
    </executor>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <invoker>
        <invoker.1/>
        <invoker.2/>
        <invoker.3/>
    </invoker>
    <recipient>
        <recipient.1/>
        <recipient.2/>
        <recipient.3/>
    </recipient>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
</testExecution>

产生所需的正确结果

<testExecution>
   <test>
      <test.1/>
      <test.2/>
      <test.3/>
   </test>
   <comment>
      <comment.1/>
      <comment.2/>
      <comment.3/>
   </comment>
   <people>
      <importantPeople>
         <executor>
            <executor.1/>
            <executor.2/>
            <executor.3/>
         </executor>
         <comment>
            <comment.1/>
            <comment.2/>
            <comment.3/>
         </comment>
         <comment>
            <comment.1/>
            <comment.2/>
            <comment.3/>
         </comment>
      </importantPeople>
      <invoker>
         <invoker.1/>
         <invoker.2/>
         <invoker.3/>
      </invoker>
   </people>
   <recipient>
      <recipient.1/>
      <recipient.2/>
      <recipient.3/>
   </recipient>
   <comment>
      <comment.1/>
      <comment.2/>
      <comment.3/>
   </comment>
   <comment>
      <comment.1/>
      <comment.2/>
      <comment.3/>
   </comment>
</testExecution>

This transformation uses and overrides the identity rule. Comments immediately following executor are retrieved using the key() function. executor , invoker and comment immediately following executor are copied in special mode named people. In the usual, anonymous mode these are matched by an empty template to avoid copying them a second time:

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

 <xsl:key name="kExecComments" match=
  "comment
          [preceding-sibling::*
              [not(self::comment)][1]
                       [self::executor]
          ]"
  use="generate-id(preceding-sibling::executor[1])"/>

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

 <xsl:template match="executor">
  <people>
    <importantPeople>
      <xsl:apply-templates mode="people"
        select=".|key('kExecComments', generate-id())"/>
    </importantPeople>
    <xsl:apply-templates mode="people" select=
    "following-sibling::invoker"/>
  </people>
 </xsl:template>

 <xsl:template match="executor|comment|invoker"
      mode="people">
    <xsl:call-template name="identity"/>
 </xsl:template>

 <xsl:template match=
  "invoker |
   comment
          [preceding-sibling::*
              [not(self::comment)][1]
                       [self::executor]
          ]"/>

</xsl:stylesheet>

when applied on the provided XML document:

<testExecution>
    <test>
        <test.1/>
        <test.2/>
        <test.3/>
    </test>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <executor>
        <executor.1/>
        <executor.2/>
        <executor.3/>
    </executor>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <invoker>
        <invoker.1/>
        <invoker.2/>
        <invoker.3/>
    </invoker>
    <recipient>
        <recipient.1/>
        <recipient.2/>
        <recipient.3/>
    </recipient>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
    <comment>
        <comment.1/>
        <comment.2/>
        <comment.3/>
    </comment>
</testExecution>

produces the wanted, correct result:

<testExecution>
   <test>
      <test.1/>
      <test.2/>
      <test.3/>
   </test>
   <comment>
      <comment.1/>
      <comment.2/>
      <comment.3/>
   </comment>
   <people>
      <importantPeople>
         <executor>
            <executor.1/>
            <executor.2/>
            <executor.3/>
         </executor>
         <comment>
            <comment.1/>
            <comment.2/>
            <comment.3/>
         </comment>
         <comment>
            <comment.1/>
            <comment.2/>
            <comment.3/>
         </comment>
      </importantPeople>
      <invoker>
         <invoker.1/>
         <invoker.2/>
         <invoker.3/>
      </invoker>
   </people>
   <recipient>
      <recipient.1/>
      <recipient.2/>
      <recipient.3/>
   </recipient>
   <comment>
      <comment.1/>
      <comment.2/>
      <comment.3/>
   </comment>
   <comment>
      <comment.1/>
      <comment.2/>
      <comment.3/>
   </comment>
</testExecution>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文