2017-04-26 42 views
0

我在PHP codeigniter框架中使用XSLT來更改XML格式。避免再生父節點(如果它已經存在於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:細節分別標記兩次姓名和地址。我不熟悉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> 
+0

請發表[MCVE] 。我們需要在您的輸入中查看「person_name」和「person_address」的父元素,以及您當前的XSLT如何處理它。 –

+0

原始XML太大且機密,無法共享。我剛剛創建了類似的場景。但是person_name和person_address將在單個節點下。可以認爲是數據節點。輸入中不使用嵌套節點。 – hrishi

回答

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

謝謝。但是我不想在frm中添加更多的輸入節點:細節。他們將來到不同的父節點下。如果我像上面那樣應用XSLT,那麼所有節點都將處於frm:details節點下。輸入中的所有節點都在數據節點 – hrishi

+0

「*如果我像上面那樣應用XSLT,那麼所有節點都將處於frm:details節點下。*」不,只有那些在同一個'data'父節點下的節點。如果你不想要所有這些,那麼只將模板選擇性地應用於你想要的模板。 –

+0

所有節點都在數據中。所有元素只有一個父節點 – hrishi

相關問題