我正在进行一个项目,该项目需要将一种结构的XML转换为另一种结构。我遇到了从另一个节点内部遍历一个节点的问题。由于我的项目涉及许多元素和属性,我创建了一个示例输入和输出XML文件。它们如下所示。
input.xml:
<GENERIC_SYSTEM_PARAMETERS>
<Companies>
<Company ID="10" Name="Cmp_1"/>
<Company ID="20" Name="Cmp_2"/>
<Company ID="30" Name="Cmp_3"/>
</Companies>
<Persons>
<Person id="1">
<Company_ID>10</Company_ID>
<Age>30</Age>
</Person>
<Person id="2">
<Company_ID>10</Company_ID>
<Age>40</Age>
</Person>
<Person id="3">
<Company_ID>20</Company_ID>
<Age>50</Age>
</Person>
</Persons>
</GENERIC_SYSTEM_PARAMETERS>
output.xml:
<Main>
<Companies>
<Company id="10" Name="Cmp_1">
<Employees>
<Employee id="1">
<Age>30</Age>
</Employee>
<Employee id="2">
<Age>40</Age>
</Employee>
</Employees>
</Company>
<Company id="20" Name="Cmp_2">
<Employees>
<Employee id="3">
<Age>50</Age>
</Employee>
</Employees>
</Company>
</Companies>
</Main>
请给我一些想法/示例xsl文件,以便进一步操作。
提前谢谢。
试试这个:
<xsl:template match="Company">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<Employees>
<xsl:apply-templates select="../../Persons/Person[Company_ID = current()/@ID]"/>
</Employees>
</xsl:copy>
</xsl:template>
并根据需要添加模板从源中的CCD_ 2节点生成CCD_。
让我们从描述开始。
与GENERIC_SYSTEM_PARAMETERS匹配的模板的行为几乎与标识模板,但更改元素名称。
匹配公司的模板包含逻辑的主要部分。要"阻止"没有员工的公司,首先要检查其员工人数。
如果数字为正数,则为:
- 复制原始打开标签
- 复制自己的属性(应用模板)
- 打开Employees元素
- 并在其中打印各自的员工,但有一些更改(见下文)
匹配Person的模板包含另一个重要部分逻辑。它:
- 更改标签名称
- 复制其自身的属性
- 仅复制其子元素Age,因此不会复制Company_ID
匹配Persons的模板实际上什么都不做,阻止标识模板对此元素的"正常"处理。
这是完整的剧本。
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="GENERIC_SYSTEM_PARAMETERS">
<Main><xsl:apply-templates select="*"/></Main>
</xsl:template>
<xsl:template match="Company">
<xsl:variable name="myEmploees" select="../../Persons/Person[Company_ID = current()/@ID]"/>
<xsl:if test="count($myEmploees) > 0">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<Employees>
<xsl:apply-templates select="../../Persons/Person[Company_ID = current()/@ID]"/>
</Employees>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="Persons"/>
<xsl:template match="Person">
<Employee>
<xsl:apply-templates select="@*|Age"/>
</Employee>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:transform>