XSLT转换问题

时间:2012-07-23 05:10:01

标签: xslt xslt-1.0

我试图转换以下内容时遇到问题。输入具有父子关系,其显示为以下级别。 Parent_Identifier标记有助于将孩子与父母联系起来。 XSLT转换的问题是什么?我使用过这篇文章中提到的转换:Xslt group parent/child,但我似乎无法让它发挥作用。

输入文件

<DBAdapterOutputCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/pcbpel/adapter/db/DBAdapter">
  <DBAdapterOutput>
    <LEVEL>1</LEVEL>      
    <IDENTIFIER>9536162</IDENTIFIER>
    <PARENT_IDENTIFIER xsi:nil="true"/>
    <LINE_NUMBER>1.1.0</LINE_NUMBER>    
  </DBAdapterOutput>

 <DBAdapterOutput>
  <LEVEL>2</LEVEL>
  <IDENTIFIER>9536165</IDENTIFIER>
  <PARENT_IDENTIFIER>9536162</PARENT_IDENTIFIER>
  <LINE_NUMBER>1.1.1</LINE_NUMBER>
  <ORDER_NUMBER>1554828</ORDER_NUMBER>
 </DBAdapterOutput>
 <DBAdapterOutput>
  <LEVEL>2</LEVEL>    
  <IDENTIFIER>9536173</IDENTIFIER>
  <PARENT_IDENTIFIER>9536162</PARENT_IDENTIFIER>
  <LINE_NUMBER>1.1.7</LINE_NUMBER>
  <ORDER_NUMBER>1554828</ORDER_NUMBER>
 </DBAdapterOutput>
 <DBAdapterOutput>
  <LEVEL>3</LEVEL>
  <IDENTIFIER>1227973</IDENTIFIER>
  <PARENT_IDENTIFIER>9536165</PARENT_IDENTIFIER>
  <LINE_NUMBER>1.1.4</LINE_NUMBER>
  <ORDER_NUMBER>1554828</ORDER_NUMBER>
 </DBAdapterOutput>
 <DBAdapterOutput>
  <LEVEL>3</LEVEL>
  <IDENTIFIER>1275015</IDENTIFIER>
  <PARENT_IDENTIFIER>9536165</PARENT_IDENTIFIER>
  <LINE_NUMBER>1.1.4</LINE_NUMBER>
  <ORDER_NUMBER>1554828</ORDER_NUMBER>
 </DBAdapterOutput>
</DBAdapterOutputCollection>

预期输出文件

<WMSAssetInterface_Input xmlns="http://siebel.com/CustomUI">
 <ListOfAsset xmlns="http://www.siebel.com/xml/ThinComergentAsset">
  <ListOfAssetHeader>
    <AssetHeader>
     <IntegrationId>9536162 1.1.0</IntegrationId>
     <ProductName>1.1.0</ProductName>
     <ListOfAssetItem>
       <AssetItem>
         <IntegrationId>9536162 1.1.0 Level=1</IntegrationId>
         <ProductName>1.1.0</ProductName>
         <ListOfAssetItem>
            <AssetItem>
               <IntegrationId>9536165 1.1.1 Level=2</IntegrationId>
               <ProductName>1.1.1</ProductName>
               <ListOfAssetItem>
                 <AssetItem>
                   <IntegrationId>1227973 1.1.4 Level=3</IntegrationId>
                   <ProductName>1.1.4</ProductName>
                  </AssetItem>
                  <AssetItem>
                    <IntegrationId>1275015 1.1.4 Level=3</IntegrationId>
                    <ProductName>1.1.4</ProductName>
                  </AssetItem>
               </ListOfAssetItem>
            </AssetItem>
            <AssetItem>
              <IntegrationId>9536173 1.1.7 Level=2</IntegrationId>
              <ProductName>1.1.7</ProductName>
            </AssetItem>
         </ListOfAssetItem>
       </AssetItem>
     </ListOfAssetItem>
   </AssetHeader>
  <ListOfAssetHeader>
 </ListOfAsset>
</WMSAssetInterface_Input>

这是我正在尝试使用的XSLT;为什么这不起作用?

<xsl:stylesheet version="1.0" xmlns:ns0="http://xmlns.oracle.com/pcbpel/adapter/db/DBAdapter" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsdLocal1="http://www.siebel.com/xml/ThinComergentAsset" xmlns:tns="http://siebel.com/CustomUI" exclude-result-prefixes="tns" >
<xsl:template match="/ns0:DBAdapterOutputCollection">
<tns:WMSAssetInterface_Input>
  <xsdLocal1:ListOfAsset>
    <xsdLocal1:ListOfAssetHeader>
      <xsdLocal1:AssetHeader>
        <xsdLocal1:IntegrationId>
          <xsl:value-of select='concat(ns0:DBAdapterOutput/ns0:IDENTIFIER," ",ns0:DBAdapterOutput/ns0:LINE_NUMBER," Level=",ns0:DBAdapterOutput/ns0:LEVEL)'/>
        </xsdLocal1:IntegrationId>
        <xsdLocal1:ProductName>
          <xsl:value-of select="ns0:DBAdapterOutput/ns0:LINE_NUMBER"/>
        </xsdLocal1:ProductName>
         <xsl:apply-templates select="ns0:DBAdapterOutputCollection/ns0:DBAdapterOutput[string-length(ns0:PARENT_IDENTIFIER)=0]" />
          </xsdLocal1:AssetHeader>
    </xsdLocal1:ListOfAssetHeader>
   </xsdLocal1:ListOfAsset>
 </tns:WMSAssetInterface_Input>
</xsl:template>

<xsl:template match="ns0:DBAdapterOutput">
  <xsdLocal1:ListOfAssetItem>
          <xsdLocal1:AssetItem>
            <xsdLocal1:IntegrationId>
              <xsl:value-of select='concat(ns0:IDENTIFIER," ",ns0:LINE_NUMBER," Level=",ns0:LEVEL)'/>
            </xsdLocal1:IntegrationId>
            <xsdLocal1:PartName>
              <xsl:value-of select="ns0:LINE_NUMBER"/>
            </xsdLocal1:PartName>
             <xsl:variable name="children" select="parent::*/ns0:DBAdapterOutput[ns0:PARENT_IDENTIFIER=current()/ns0:IDENTIFIER]" />
    <xsl:if test="$children">
        <xsdLocal1:ListOfAssetItem>
          <xsdLocal1:AssetItem>
            <xsl:apply-templates select="$children" />
         </xsdLocal1:AssetItem>
          </xsdLocal1:ListOfAssetItem>
    </xsl:if>
         </xsdLocal1:AssetItem>
       </xsdLocal1:ListOfAssetItem>
   </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:1)

两个编译时错误:

  1. tns:前缀未绑定到任何名称空间。
  2. 样式表中的这一行是无稽之谈。

    <xsl:value-of select='concat(/ns0:IDENTIFIER," ",/ns0:LINE_NUMBER," Level=",/ns0:DBAdapterOutput/ns0:LEVEL')'/>
    
  3. 缺少样式表的关闭标记。

  4. 更新

    我修复了样式表中的几个错误:

    1. &lt; xsl:template match =“ns0:DBAdapterOutput /”/&gt;无效。删除最终/。
    2. 与&lt; xsl:template match =“/ ns0:DBAdapterOutputCollection”&gt;
    3. 类似

      更新

      这里的技术是递归地使用xsl:apply-templates来深入了解关卡。仅通过比较两个链接字段就可以将记录与其父母进行匹配,但另一种方法是使用密钥。

      此XSLT 1.0样式表......

      <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:ns0="http://xmlns.oracle.com/pcbpel/adapter/db/DBAdapter"
        xmlns:xsdLocal1="http://www.siebel.com/xml/ThinComergentAsset"
        exclude-result-prefixes="xsl xsdLocal1 ns0">
      <xsl:output method="xml" indent="yes"/>
      
      <xsl:template match="/">
       <WMSAssetInterface_Input xmlns="http://siebel.com/CustomUI">
        <ListOfAsset xmlns="http://www.siebel.com/xml/ThinComergentAsset">
         <ListOfAssetHeader>
           <xsl:apply-templates select="*/ns0:DBAdapterOutput[ns0:LEVEL=1]" /> 
         </ListOfAssetHeader>
        </ListOfAsset>
       </WMSAssetInterface_Input>
      </xsl:template>
      
      <xsl:template match="ns0:DBAdapterOutput[ns0:LEVEL=1]"
        xmlns="http://www.siebel.com/xml/ThinComergentAsset">
        <AssetHeader>
          <IntegrationId>
            <xsl:value-of select="concat(ns0:IDENTIFIER,' ',ns0:LINE_NUMBER)" /> 
          </IntegrationId>
          <ProductName>
            <xsl:value-of select="ns0:LINE_NUMBER" />
          </ProductName>
          <ListOfAssetItem>
            <xsl:apply-templates select="../ns0:DBAdapterOutput
                      [           ns0:LEVEL=
                       (current()/ns0:LEVEL+1)]" /> 
          </ListOfAssetItem>
        </AssetHeader>
      </xsl:template>
      
      <xsl:template match="ns0:DBAdapterOutput[ns0:LEVEL &gt; 1]"
            xmlns="http://www.siebel.com/xml/ThinComergentAsset">
        <AssetItem>
          <IntegrationId>
            <xsl:value-of select="concat(ns0:IDENTIFIER,' ',ns0:LINE_NUMBER,
            ' Level=', ns0:LEVEL/text()-1)" /> 
          </IntegrationId>
          <ProductName>
            <xsl:value-of select="ns0:LINE_NUMBER" />
          </ProductName>
          <xsl:if test="../ns0:DBAdapterOutput
                      [ns0:PARENT_IDENTIFIER = current()/ns0:IDENTIFIER]">
           <ListOfAssetItem>
            <xsl:apply-templates select="../ns0:DBAdapterOutput
                      [ns0:PARENT_IDENTIFIER = current()/ns0:IDENTIFIER]" /> 
           </ListOfAssetItem>
          </xsl:if>
        </AssetItem>
      </xsl:template>
      
      </xsl:stylesheet>
      

      ...当应用于样本输入时,将产生...

      <WMSAssetInterface_Input xmlns="http://siebel.com/CustomUI">
        <ListOfAsset xmlns="http://www.siebel.com/xml/ThinComergentAsset">
          <ListOfAssetHeader>
            <AssetHeader>
              <IntegrationId>9536162 1.1.0</IntegrationId>
              <ProductName>1.1.0</ProductName>
              <ListOfAssetItem>
                <AssetItem>
                  <IntegrationId>9536165 1.1.1 Level=1</IntegrationId>
                  <ProductName>1.1.1</ProductName>
                  <ListOfAssetItem>
                    <AssetItem>
                      <IntegrationId>1227973 1.1.4 Level=2</IntegrationId>
                      <ProductName>1.1.4</ProductName>
                    </AssetItem>
                    <AssetItem>
                      <IntegrationId>1275015 1.1.4 Level=2</IntegrationId>
                      <ProductName>1.1.4</ProductName>
                    </AssetItem>
                  </ListOfAssetItem>
                </AssetItem>
                <AssetItem>
                  <IntegrationId>9536173 1.1.7 Level=1</IntegrationId>
                  <ProductName>1.1.7</ProductName>
                </AssetItem>
              </ListOfAssetItem>
            </AssetHeader>
          </ListOfAssetHeader>
        </ListOfAsset>
      </WMSAssetInterface_Input>
      

      这与您所说的预期产量略有不同,但仅仅是因为,恕我直言,列出的预期产出中的错误。我相信这可以满足您的需求。

答案 1 :(得分:1)

首先,关于代码的不可读性的观察 - 请在将来的问题中提供缩短代码的短行代码!

有一个主要问题可以轻松纠正。

更改此

<xsl:apply-templates select=
"ns0:DBAdapterOutputCollection/ns0:DBAdapterOutput
             [string-length(ns0:PARENT_IDENTIFIER)=0]" />

到此

<xsl:apply-templates select=
"ns0:DBAdapterOutput
             [string-length(ns0:PARENT_IDENTIFIER)=0]" />

必须修改的XSLT指令位于模板中,当前节点位于顶部 ns0:DBAdapterOutputCollection元素。它指定模板应该应用于满足谓词中条件的任何 grand-children ns0:DBAdapterOutput元素,并且该元素是当前任何ns0:DBAdapterOutputCollection子元素的子元素节点

但是,当前节点(顶部ns0:DBAdapterOutputCollection元素)没有子节点ns0:DBAdapterOutputCollection子节点,并且此xsl:apply-templates指令选择了无节点执行。

完成上述简单的代码更改后,转换的结果似乎可能是想要的

<?xml version="1.0" encoding="utf-8"?>
<tns:WMSAssetInterface_Input xmlns:tns="http://siebel.com/CustomUI" xmlns:ns0="http://xmlns.oracle.com/pcbpel/adapter/db/DBAdapter" xmlns:xsdLocal1="http://www.siebel.com/xml/ThinComergentAsset">
    <xsdLocal1:ListOfAsset>
        <xsdLocal1:ListOfAssetHeader>
            <xsdLocal1:AssetHeader>
                <xsdLocal1:IntegrationId>9536162 1.1.0 Level=1</xsdLocal1:IntegrationId>
                <xsdLocal1:ProductName>1.1.0</xsdLocal1:ProductName>
                <xsdLocal1:ListOfAssetItem>
                    <xsdLocal1:AssetItem>
                        <xsdLocal1:IntegrationId>9536162 1.1.0 Level=1</xsdLocal1:IntegrationId>
                        <xsdLocal1:PartName>1.1.0</xsdLocal1:PartName>
                        <xsdLocal1:ListOfAssetItem>
                            <xsdLocal1:AssetItem>
                                <xsdLocal1:ListOfAssetItem>
                                    <xsdLocal1:AssetItem>
                                        <xsdLocal1:IntegrationId>9536165 1.1.1 Level=2</xsdLocal1:IntegrationId>
                                        <xsdLocal1:PartName>1.1.1</xsdLocal1:PartName>
                                        <xsdLocal1:ListOfAssetItem>
                                            <xsdLocal1:AssetItem>
                                                <xsdLocal1:ListOfAssetItem>
                                                    <xsdLocal1:AssetItem>
                                                        <xsdLocal1:IntegrationId>1227973 1.1.4 Level=3</xsdLocal1:IntegrationId>
                                                        <xsdLocal1:PartName>1.1.4</xsdLocal1:PartName>
                                                    </xsdLocal1:AssetItem>
                                                </xsdLocal1:ListOfAssetItem>
                                                <xsdLocal1:ListOfAssetItem>
                                                    <xsdLocal1:AssetItem>
                                                        <xsdLocal1:IntegrationId>1275015 1.1.4 Level=3</xsdLocal1:IntegrationId>
                                                        <xsdLocal1:PartName>1.1.4</xsdLocal1:PartName>
                                                    </xsdLocal1:AssetItem>
                                                </xsdLocal1:ListOfAssetItem>
                                            </xsdLocal1:AssetItem>
                                        </xsdLocal1:ListOfAssetItem>
                                    </xsdLocal1:AssetItem>
                                </xsdLocal1:ListOfAssetItem>
                                <xsdLocal1:ListOfAssetItem>
                                    <xsdLocal1:AssetItem>
                                        <xsdLocal1:IntegrationId>9536173 1.1.7 Level=2</xsdLocal1:IntegrationId>
                                        <xsdLocal1:PartName>1.1.7</xsdLocal1:PartName>
                                    </xsdLocal1:AssetItem>
                                </xsdLocal1:ListOfAssetItem>
                            </xsdLocal1:AssetItem>
                        </xsdLocal1:ListOfAssetItem>
                    </xsdLocal1:AssetItem>
                </xsdLocal1:ListOfAssetItem>
            </xsdLocal1:AssetHeader>
        </xsdLocal1:ListOfAssetHeader>
    </xsdLocal1:ListOfAsset>
</tns:WMSAssetInterface_Input>