如何使用 XSLT 在 xml 文件中找到一个元素并将其放置在另一个标签中?

How to find an element in xml file and place that inside another tag using XSLT?

我有一个 xml 文件 ab.xml

<?xml version="1.0"?>
<TestSuite Name="DM123">
  <Group Name="TestRoot" ExecutionPolicy="AnyDeviceAnyOrder">
    <Parameters>
      <Parameter Type="Integer" Name="maxA" Value="1" />
      <Parameter Type="Integer" Name="MaxB" Value="120" />
      <Parameter Type="String" Name="MaxC" Value="integration" />
    </Parameters>
    <Children>
      <Group Name="Cam1">
        <Parameters>
           <Parameter Type="Integer" Name="maxA" />
           <Parameter Type="Integer" Name="MaxB"/>
           <Parameter Type="String" Name="MaxC" />
        </Parameters>
        <Children>
          <Group Name="Field1">
            <Parameters>
              <Parameter Type="Integer" Name="maxA" />
              <Parameter Type="Integer" Name="MaxB" Value="1600" />
              <Parameter Type="String" Name="MaxC" />
            </Parameters>
            <Children>
              <Test Name="Test1" Namespace="TestCases">
                <Parameters>
                  <Parameter Type="Device" Name="Device">
                    <Requirements>
                      <Requirement TypeId="a76" Source="User" />
                      <Requirement TypeId="2c9" Source="User" />
                    </Requirements>
                  </Parameter>
                </Parameters>
              </Test>
            </Children>
          </Group>
          <Group Name="Field3">
            <Parameters>
              <Parameter Type="Integer" Name="maxA" />
              <Parameter Type="Integer" Name="MaxB" />
              <Parameter Type="String" Name="MaxC" Value="51" />
            </Parameters>
            <Children>
              <Test Name="Test5" Namespace="TestCases">
                <Parameters>
                  <Parameter Type="Dev" Name="Dev">
                    <Requirements>
                      <Requirement TypeId="a76" Source="User" />
                      <Requirement TypeId="2c9" Source="User" />
                    </Requirements>
                  </Parameter>
                </Parameters>
              </Test>
            </Children>
          </Group>
        </Children>  
      </Group>
    </Children>
  </Group>
  <Models>
    <Model Name="DD1" />
  </Models>
</TestSuite>

我有这个 XSLT

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

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

    <xsl:template match="Group[@Name = 'TestRoot']/Children">
     <xsl:copy>
      <xsl:apply-templates select=".//Test"/>
     </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

这是给我这个结果:- output.xml

<?xml version="1.0" encoding="UTF-8"?>
<TestSuite Name="DM123">
   <Group Name="TestRoot" ExecutionPolicy="AnyDeviceAnyOrder">
      <Parameters>
         <Parameter Type="Integer" Name="maxA" Value="1"/>
         <Parameter Type="Integer" Name="MaxB" Value="120"/>
         <Parameter Type="String" Name="MaxC" Value="integration"/>
      </Parameters>
      <Children>
         <Test Name="Test1" Namespace="TestCases">
            <Parameters>
               <Parameter Type="Device" Name="Device">
                  <Requirements>
                     <Requirement TypeId="a76" Source="User"/>
                     <Requirement TypeId="2c9" Source="User"/>
                  </Requirements>
               </Parameter>
            </Parameters>
         </Test>
         <Test Name="Test5" Namespace="TestCases">
            <Parameters>
               <Parameter Type="Dev" Name="Dev">
                  <Requirements>
                     <Requirement TypeId="a76" Source="User"/>
                     <Requirement TypeId="2c9" Source="User"/>
                  </Requirements>
               </Parameter>
            </Parameters>
         </Test>
       </Children>
   </Group>
   <Models>
      <Model Name="DD1"/>
   </Models>
</TestSuite>

基本上 xslt 代码删除了在 TestRoot 组中定义的重复参数。因此,在 TestRoot 组中定义的参数再次在其他组中定义,因此使用当前的 XSLT 代码,它基本上删除了所有子组及其参数,并将测试标签移动到子标签中。

点击Demo

但是如果你看到在其参数名MaxB的Field1 Group中有一个value字段,它正在覆盖Group TestRoot的上述参数。我想要的是,如果是这种情况,我想复制该参数并将其粘贴到 Group Field1 下的测试标签中,同样适用于 field3 Group。

期望的输出:-

<?xml version="1.0"?>
<TestSuite Name="DM123">
  <Group Name="TestRoot" ExecutionPolicy="AnyDeviceAnyOrder">
    <Parameters>
      <Parameter Type="Integer" Name="maxA" Value="1" />
      <Parameter Type="Integer" Name="MaxB" Value="120" />
      <Parameter Type="String" Name="MaxC" Value="integration" />
    </Parameters>
    <Children>
      <Test Name="Test1" Namespace="TestCases">
        <Parameters>
           <Parameter Type="Integer" Name="MaxB" Value="1600" />
           <Parameter Type="Device" Name="Device">
             <Requirements>
               <Requirement TypeId="a76" Source="User" />
               <Requirement TypeId="2c9" Source="User" />
             </Requirements>
           </Parameter>
        </Parameters>
      </Test>
      <Test Name="Test5" Namespace="TestCases">
            <Parameters>
               <Parameter Type="String" Name="MaxC" Value="51" />
               <Parameter Type="Dev" Name="Dev">
                  <Requirements>
                     <Requirement TypeId="a76" Source="User"/>
                     <Requirement TypeId="2c9" Source="User"/>
                  </Requirements>
               </Parameter>
            </Parameters>
         </Test>
   </Children>
  </Group>
  <Models>
    <Model Name="DD1" />
  </Models>
</TestSuite>

如何使用 XSLT 获得所需的输出?提前致谢

我想你想添加一个模板

<xsl:template match="Test/Parameters">
    <xsl:copy>
        <xsl:apply-templates select="@* | ../../preceding-sibling::Parameters[1]/Parameter[@Value] | node()"/>
    </xsl:copy>
</xsl:template>

如果我对你的理解是正确的,你想复制具有@Value 属性的参数。在这种情况下,您可以添加匹配参数的模板并添加这些参数。

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

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

<xsl:template match="Group[@Name = 'TestRoot']/Children">
    <xsl:copy>
        <xsl:apply-templates select=".//Test"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Parameters[ancestor::Children]">
    <xsl:copy>
        <xsl:if test="ancestor::Group[1]/Parameters/Parameter[@Value]">
            <xsl:copy-of select="ancestor::Group[1]/Parameters/Parameter[@Value]"/>
        </xsl:if>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

并且根据您的预期输出,您只需要匹配作为 Children 元素的祖先的参数。