1

我在尝试转换以下内容时遇到问题。输入具有父子关系,如下所示。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>
4

2 回答 2

1

两个编译时错误:

  1. tns: 前缀未绑定到任何命名空间。

  2. 样式表中的这一行是无稽之谈。

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

更新

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

  1. <xsl:template match="ns0:DBAdapterOutput/" /> 无效。删除最后的 / 。
  2. 与 <xsl:template match="/ns0:DBAdapterOutputCollection"> 类似

更新

这里的技术是递归地使用 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>

这与您声明的预期输出略有不同,但这仅仅是因为,恕我直言,列出的预期输出中存在错误。我相信这可以满足您的需求。

于 2012-07-23T06:18:42.657 回答
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元素的模板中。它指定模板应应用于满足谓词中条件的 任何 元素,并且该元素是当前节点的任何子节点的子节点。ns0:DBAdapterOutputns0: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>
于 2012-07-23T12:37:02.720 回答