如何在新父项下移动多个元素,但只移动一次?

How to move several elements under new parent, but only once?

我想将某些元素嵌套在新父项下,但仅限于某些 id 值。一旦嵌套,不得重复。

来源:

<root name="root 1">
  <elem id="java" value="val1"/>
  <elem id="python" value="val2"/>
  <elem id="chair" value="val3"/>
</root>

想要的结果:

<root name="root 1">
  <container name="lang">
    <elem id="java" value="val1"/>
    <elem id="python" value="val2"/>
  </container>
  <elem id="chair" value="val3"/>
</root>

额外问题:有可能并非所有嵌套目标都可用。然而,它们应该嵌套空值。

来源:

<root name="root 1">
  <elem id="java" value="val1"/>
  <elem id="chair" value="val3"/>
</root>

目标:

<root name="root 1">
  <container name="lang">
    <elem id="java" value="val1"/>
    <elem id="python" value=""/>
  </container>
  <elem id="chair" value="val3"/>
</root>

我的结果一直在重复container。我怎样才能按预期转换它?

您可以循环遍历 XSLT 2.0 中的字符串列表。所以这可能会起作用:

<?xml version="1.0" encoding="UTF-8"?>
<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="root">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:variable name="elems" select="elem"/>
      <container>
        <xsl:for-each select="('java', 'python')">
          <elem id="{.}" value="{string($elems[@id=current()]/@value)}"/>
        </xsl:for-each>
      </container>

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

  <xsl:template match="elem[@id=('java', 'python')]"/>
</xsl:stylesheet>