如果父节点已存在于XML中,则避免重新生成父节点

时间:2017-04-26 06:35:26

标签: xml xslt

我在PHP codeigniter框架中使用 XSLT 来更改XML的格式。

输入就像

<data>
   <person_name>value</person_name>
   <person_address>value</person_address>
   <person_bloodGroup>value</person_bloodGroup>
   <person_weight>value</person_weight>
</data> 

我想将其转换为

<data>
  <frm:details>
      <d:name>value</d:name>
      <d:address>value</d:address>
  </frm:details>
  <frm:health>
      <d:bloodGroup>value</d:bloodGroup>
      <d:weight>value</d:weight>
  </frm:health>
</data>

我正在使用XSLT

<xsl:template match="person_name">
    <frm:details>
        <d:name>
            <xsl:apply-templates/>
        </d:name>
    </frm:details>
</xsl:template>

<xsl:template match="person_address">
    <frm:details>
        <d:address>
            <xsl:apply-templates/>
        </d:address>
    </frm:details>
</xsl:template>

<xsl:template match="person_bloodGroup">
    <frm:health>
        <d:bloodGroup>
            <xsl:apply-templates/>
        </d:bloodGroup>
    </frm:health>
</xsl:template>

<xsl:template match="person_address">
    <frm:health>
        <d:weight>
            <xsl:apply-templates/>
        </d:weight>
    </frm:health>
</xsl:template>

但它会为名称和地址分别生成frm:details标记两次。我不熟悉XSLT。有没有办法,所以我可以检查父节点是否已经存在然后在其中添加子节点而不重新生成父节点。 我的输出为

<frm:details>
    <d:name>value</d:name>
</frm:details>

<frm:details>
    <d:address>value</d:address>
</frm:details>

<frm:health>
    <d:bloodGroup>value</d:bloodGroup>
</frm:health>

<frm:health>
    <d:weight>value</d:weight>
</frm:health>

1 个答案:

答案 0 :(得分:1)

添加与data节点匹配的模板,并在那里创建父元素。然后应用处理相关子节点的模板(并从中删除父节点的创建):

<xsl:template match="/data">
    <xsl:copy>
        <frm:details>
            <xsl:apply-templates select="person_name | person_address"/>
        </frm:details>
        <frm:health>
            <xsl:apply-templates select="person_bloodGroup | person_weight"/>
        </frm:health>
    </xsl:copy>
</xsl:template>

<xsl:template match="person_name">
    <d:name>
        <xsl:apply-templates />
    </d:name>
</xsl:template>

<xsl:template match="person_address">
    <d:address>
        <xsl:apply-templates/>
    </d:address>
</xsl:template>

<xsl:template match="person_bloodGroup">
    <d:bloodGroup>
        <xsl:apply-templates/>
    </d:bloodGroup>
</xsl:template>

<xsl:template match="person_weight">
    <d:weight>
        <xsl:apply-templates/>
    </d:weight>
</xsl:template>

请注意,您可以将其缩短为:

<xsl:template match="/data">
    <xsl:copy>
        <frm:details>
            <d:name>
                <xsl:value-of select="person_name"/>
            </d:name>
            <d:address>
                <xsl:value-of select="person_address"/>
            </d:address>
        </frm:details>
        <frm:health>
            <d:bloodGroup>
                <xsl:value-of select="person_bloodGroup"/>
            </d:bloodGroup>
            <d:weight>
                <xsl:value-of select="person_weight"/>
            </d:weight>
        </frm:health>
    </xsl:copy>
</xsl:template>