2015-10-06 99 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