使用XSL将一个XML结构转换为另一个XML结构

时间:2017-10-24 15:14:16

标签: xml xslt xsd xslt-1.0 xslt-2.0

我正在开发一个需要将一个结构的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文件以继续。

提前谢谢你。

2 个答案:

答案 0 :(得分:0)

试试这个:

<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>

并根据需要添加模板以从源中的Employee节点生成Person个节点。

答案 1 :(得分:0)

让我们从描述开始。

匹配 GENERIC_SYSTEM_PARAMETERS 的模板几乎就像 身份模板,但更改元素名称。

匹配 Company 的模板包含逻辑的主要部分。 到&#34;阻止&#34;没有员工的公司从检查开始 员工人数。

如果数字为正数,则为:

  • 复制原始开场标记
  • 复制自己的属性( apply-templates ),
  • 打开员工元素,
  • 并在其中打印相应的员工,但有一些更改(见下文)。

匹配 Person 的模板包含另一个重要部分 的逻辑。它:

  • 更改标记名称
  • 复制自己的属性,
  • 仅复制其子年龄元素,因此不会复制 Company_ID

匹配 Persons 的模板实际上什么都不做,阻塞 &#34;正常&#34;通过身份模板处理此元素。

这里是完整的脚本。

<?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) &gt; 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>