如何使用 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 元素的祖先的参数。
我有一个 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 元素的祖先的参数。