将现有节点添加到另一个节点的子节点

时间:2009-12-31 12:08:27

标签: xslt

我有以下XML,我想使用XSLT将其转换为我想要的XML,我已经成功了但不是整个问题都解决了。所以 我需要帮助

鉴于是我的输入XML

<?xml version = '1.0'?>
<ROWSET>
<irp_account num="1">
<IRP_CARRIER_ID_NUMBER>274845</IRP_CARRIER_ID_NUMBER>
<IRP_ACCOUNT_NUMBER>55002</IRP_ACCOUNT_NUMBER>
</irp_account>     
<irp_account num="97">
<IRP_CARRIER_ID_NUMBER>957858</IRP_CARRIER_ID_NUMBER>
<IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER>
<NAME_TYPE>LG</NAME_TYPE>
<NAME>SONNY DAVIS INC</NAME>
<ADDRESS_TYPE>MA</ADDRESS_TYPE>
</irp_account>
<irp_account num="98">
<IRP_CARRIER_ID_NUMBER>957858</IRP_CARRIER_ID_NUMBER>
<IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER> 
<NAME_TYPE>LG</NAME_TYPE>
<NAME>SONNY DAVIS INC</NAME>
<ADDRESS_TYPE>PH</ADDRESS_TYPE>
</irp_account> 
</ROWSET>

使用XSLT我想生成像这样的输出XML。

<?xml version="1.0"?> 
<T0020>
<IRP_ACCOUNT>
<IRP_CARRIER_ID_NUMBER>274845</IRP_CARRIER_ID_NUMBER> 
<IRP_ACCOUNT_NUMBER>55002</IRP_ACCOUNT_NUMBER> 
<IRP_NAME>
<NAME_TYPE>LG</NAME_TYPE> 
<NAME>A P SUPPLY CO</NAME> 
<IRP_ADDRESS> 
<ADDRESS_TYPE>PH</ADDRESS_TYPE> 
</IRP_ADDRESS>
<IRP_ADDRESS>
<ADDRESS_TYPE>MA</ADDRESS_TYPE> 
</IRP_ADDRESS>
</IRP_NAME>
</IRP_ACCOUNT>
</T0020>

我给出了样本输出,只有元素来节省空间。

我在XSLT下面尝试过,但它没有给出欲望结果

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/ROWSET"> 
<xsl:element name="T0020">
<xsl:apply-templates select="irp_account"/>
</xsl:element> 
</xsl:template>
<xsl:template match="irp_account">
<xsl:element name="IRP_ACCOUNT">
<xsl:apply-templates select="IRP_CARRIER_ID_NUMBER"/>
<xsl:apply-templates select="IRP_ACCOUNT_NUMBER"/>
<xsl:apply-templates select="IRP_ACCOUNT_TYPE"/>
<xsl:apply-templates select="NAME_TYPE"/> 
<xsl:apply-templates select="ADDRESS_TYPE"/>
</xsl:element> 
</xsl:template>
<xsl:template match="IRP_CARRIER_ID_NUMBER">
<xsl:copy-of select="descendant-or-self::IRP_CARRIER_ID_NUMBER"/>
</xsl:template>
<xsl:template match="IRP_ACCOUNT_NUMBER">
<xsl:copy-of select="descendant-or-self::IRP_ACCOUNT_NUMBER"/>
</xsl:template>
<xsl:template match="IRP_ACCOUNT_TYPE">
<xsl:copy-of select="descendant-or-self::IRP_ACCOUNT_TYPE"/>
</xsl:template>
<xsl:template match="NAME_TYPE"> 
<xsl:element name="IRP_NAME">
<xsl:copy-of select="descendant-or-self::NAME_TYPE"/>
<xsl:copy-of select="following-sibling::NAME"/>
</xsl:element> 
</xsl:template> 
<xsl:template match="ADDRESS_TYPE">
<xsl:element name="IRP_ADDRESS">
<xsl:copy-of select="descendant-or-self::ADDRESS_TYPE"/>
<xsl:copy-of select="following-sibling::NAME"/>
</xsl:element> 
</xsl:template>
</xsl:stylesheet>

请帮忙

2 个答案:

答案 0 :(得分:0)

你想要复杂化。文本元素按原样输出 - 如果需要动态生成标记名,请使用xsl:element。另请注意使用<xsl:copy>逐字复制不需要任何更改的内容。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/ROWSET"> 
    <T0020>
        <xsl:apply-templates/>
    </T0020>
</xsl:template>

<xsl:template match="/ROWSET/irp_account"> 
    <IRP_ACCOUNT>
        <xsl:copy-of select="IRP_CARRIER_IP_NUMBER"/>
        <xsl:copy-of select="IRP_ACCOUNT_NUMBER"/>
        <xsl:if test="NAME">
            <IRP_NAME>
                <xsl:copy-of select="NAME"/>
                <xsl:copy-of select="NAME_TYPE"/>
            </IRP_NAME>
        </xsl:if>
        <xsl:if test="ADDRESS_TYPE">
            <IRP_ADDRESS>
                <xsl:copy-of select="ADDRESS_TYPE"/>
            </IRP_ADDRESS>
        </xsl:if>
    </IRP_ACCOUNT>
</xsl:template>
</xsl:stylesheet>

要使用相同的IRP_CARRIER_IP_NUMBER对多个项目进行分组,您可以执行以下操作:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:variable name="accounts" select="/ROWSET/irp_account"/>
  <xsl:template match="/ROWSET"> 
  <T0020>
    <xsl:for-each select="$accounts">
      <xsl:variable name="pos" select="position()"/>
      <xsl:variable name="num" select="./IRP_ACCOUNT_NUMBER/text()"/>
      <xsl:if test="count($accounts[position() &lt; $pos]/IRP_ACCOUNT_NUMBER[text()=$num])=0">
        <xsl:variable name="all-accounts" select="$accounts[IRP_ACCOUNT_NUMBER/text() = $num]"/>
        <IRP_ACCOUNT>
          <xsl:copy-of select="IRP_ACCOUNT_NUMBER"/>
          <xsl:if test="$all-accounts[NAME_TYPE]">
            <IRP_NAME>
              <!-- note: we just take the first name, and don't check 
               if the name is the same for all releated accounts --> 
              <xsl:copy-of select="NAME"/> 
              <!-- note: we just list all name types, and don't check 
               for duplicates --> 
              <xsl:for-each select="$all-accounts">
                <xsl:copy-of select="NAME_TYPE"/> 
              </xsl:for-each>
            </IRP_NAME>
          </xsl:if>
          <xsl:if test="$all-accounts[ADDRESS_TYPE]">
            <IRP_ADDRESS>
              <!-- note: we just list all address types, and don't check 
               for duplicates --> 
              <xsl:for-each select="$all-accounts">
                <xsl:copy-of select="ADDRESS_TYPE"/> 
              </xsl:for-each>
            </IRP_ADDRESS>
          </xsl:if>
        </IRP_ACCOUNT>
      </xsl:if>
    </xsl:for-each>
  </T0020>
</xsl:template>

(如果有帮助,别忘了接受答案)

答案 1 :(得分:0)

感谢Roland的回答,当我使用此

进行转换时,它非常有用
<?xml version = '1.0'?>
<ROWSET>
   <irp_account num="97">
      <IRP_CARRIER_ID_NUMBER>957858</IRP_CARRIER_ID_NUMBER>
      <IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER>
      <IRP_ACCOUNT_TYPE>I</IRP_ACCOUNT_TYPE>
      <NAME_TYPE>LG</NAME_TYPE>
      <NAME>SONNY DAVIS INC</NAME>
      <ADDRESS_TYPE>MA</ADDRESS_TYPE>
   </irp_account>
   <irp_account num="98">
      <IRP_CARRIER_ID_NUMBER>957858</IRP_CARRIER_ID_NUMBER>
      <IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER>
      <IRP_ACCOUNT_TYPE>I</IRP_ACCOUNT_TYPE>
      <NAME_TYPE>LG</NAME_TYPE>
      <NAME>SONNY DAVIS INC</NAME>
      <ADDRESS_TYPE>PH</ADDRESS_TYPE>
   </irp_account>     
</ROWSET>

它给了我以下输出

<?xml version="1.0" encoding="utf-8" ?> 
<T0020>
 <IRP_ACCOUNT>
    <IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER> 
    <IRP_NAME>
        <NAME>SONNY DAVIS INC</NAME> 
        <NAME_TYPE>LG</NAME_TYPE> 
    </IRP_NAME>
    <IRP_ADDRESS>
      <ADDRESS_TYPE>MA</ADDRESS_TYPE> 
    </IRP_ADDRESS>
  </IRP_ACCOUNT>

  <IRP_ACCOUNT>
      <IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER> 
      <IRP_NAME>
           <NAME>SONNY DAVIS INC</NAME> 
           <NAME_TYPE>LG</NAME_TYPE> 
      </IRP_NAME>
       <IRP_ADDRESS>
          <ADDRESS_TYPE>PH</ADDRESS_TYPE> 
       </IRP_ADDRESS>
  </IRP_ACCOUNT>
</T0020>

现在我的输出XML可能采用以下格式

<?xml version="1.0" encoding="utf-8" ?> 
    <T0020>
     <IRP_ACCOUNT>
        <IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER> 
        <IRP_NAME>
            <NAME>SONNY DAVIS INC</NAME> 
            <NAME_TYPE>LG</NAME_TYPE> 
             <IRP_ADDRESS>
                  <ADDRESS_TYPE>MA</ADDRESS_TYPE> 
                  <ADDRESS_TYPE>PH</ADDRESS_TYPE> 
             </IRP_ADDRESS>
        </IRP_NAME>        
      </IRP_ACCOUNT>

    </T0020>

我是否可以将地址类型分组为其他标签的值,如(IRP_CARRIER_ID_NUMBER&gt;,)相同。

非常感谢您提供精彩的帮助...