2015-10-06 57 views
0

這是一個XML文件,我想變換:用XSLT展開XML可能嗎?

<?xml version="1.0" encoding="utf-8"?> 
<batchResponse> 
    <searchResponse> 
    <searchResultEntry dn="uid=Massan Jill"> 
     <attr name="cn"> 
     <value>Massan, Jill</value> 
     </attr> 
     <attr name="userAccount"> 
     <value>ABC1234567</value> 
     <value>DEF1234567</value> 
     </attr> 
    </searchResultEntry> 
    </searchResponse> 
</batchResponse> 

這是我爲轉型創造了XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
    <entry> 
     <xsl:for-each select="batchResponse/searchResponse/searchResultEntry"> 
     <xsl:if test="@dn!='' and contains(@dn, 'uid=')">     
      <import>  
      <cn> 
       <xsl:value-of select="attr[@name='cn']/value"/> 
      </cn> 
      <userAccount> 
       <xsl:value-of select="attr[@name='userAccount']/value"/> 
      </userAccount> 
      </import>  
     </xsl:if> 
     </xsl:for-each> 
    </entry> 
    </xsl:template> 
</xsl:stylesheet> 

這是轉換後的XML:

<?xml version="1.0" encoding="UTF-8"?> 
<entry> 
    <import> 
     <cn>Massan, Jill</cn> 
     <userAccount>ABC1234567</userAccount> 
    </import> 
</entry> 

我的問題是,原始XML數據包含「userAccount」的幾個值,並且轉換後的XML應該通過展開這些數據來反映這一點le import-entries like this:

<?xml version="1.0" encoding="UTF-8"?> 
<entry> 
    <import> 
     <cn>Massan, Jill</cn> 
     <userAccount>ABC1234567</userAccount> 
    </import> 
    <import> 
    <cn>Massan, Jill</cn> 
    <userAccount>DEF1234567</userAccount> 
    </import> 
</entry> 

這是甚至可能與xslt,如果是這樣,如何?

回答

1

您可以使用xsl:for-each選擇每個「用戶賬戶」項,然後創建一個import記錄的這個

每一個試試這個XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:template match="/"> 
    <entry> 
     <xsl:for-each select="batchResponse/searchResponse/searchResultEntry"> 
     <xsl:if test="@dn!='' and contains(@dn, 'uid=')">     
      <xsl:for-each select="attr[@name='userAccount']/value"> 
      <import>  
      <cn> 
       <xsl:value-of select="../../attr[@name='cn']/value"/> 
      </cn> 
      <userAccount> 
       <xsl:value-of select="."/> 
      </userAccount> 
      </import>  
      </xsl:for-each> 
     </xsl:if> 
     </xsl:for-each> 
    </entry> 
    </xsl:template> 
</xsl:stylesheet> 

注意表達<xsl:value-of select="../../attr[@name='cn']/value"/>來獲取用戶名稱。這是因爲您位於value元素上,所以您需要返回層次結構以獲取用戶名(..表示獲取當前節點的父節點)。

其實你可以將兩個xsl:for-each語句和xsl:if合併成一個,來簡化事情。試試這個XSLT太

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:template match="/"> 
    <entry> 
     <xsl:for-each select="batchResponse/searchResponse/searchResultEntry[@dn!='' and contains(@dn, 'uid=')]/attr[@name='userAccount']/value"> 
     <import>  
     <cn> 
      <xsl:value-of select="../../attr[@name='cn']/value"/> 
     </cn> 
     <userAccount> 
      <xsl:value-of select="."/> 
     </userAccount> 
     </import>  
     </xsl:for-each> 
    </entry> 
    </xsl:template> 
</xsl:stylesheet> 
+0

'@dn!= '',包含(@dn,爲 'uid =')'可以縮短到'包含(@dn,爲 'uid =')'。 –

+0

謝謝蒂姆!這真的有很大的幫助(和你的解決方案,順便說一句)。此外,謝謝你提供有關縮短病情的提示。 – Mephisztoe