可以使用XSLT展开XML吗?

时间:2015-10-06 09:48:28

标签: xml xslt transformation

这是我想要转换的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>

这是我为Transformation创建的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应通过将此类数据展开到多个导入条目来反映这一点:

<?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 个答案:

答案 0 :(得分:1)

您可以使用xsl:for-each选择每个&#34;用户帐户&#34;输入,然后为每个

创建一个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>