XSL - 使用当前上下文的值查找另一个节点值

问题描述:

我有一个使用PackageID值引用文档中其他节点的XML。 我想使用当前节点的结果,然后查找包含文档中匹配PackageID的另一个节点的值。 在这种情况下,我想获取SourcePackage/PackageName或MaterialPackage/PackageName或另一个具有与CompositionPackage/PackageTracks/TimelineTrack/TrackSegment/SourcePackageID中的PackageID值匹配的CompositionPackage的值。XSL - 使用当前上下文的值查找另一个节点值

示例XML:

<AAG version="1.1"> 
<Preface> 
    <ContentStorage> 
     <SourcePackage> 
     <PackageTracks> 
      <TimelineTrack> 
      <TrackSegment> 
       <ComponentLength>5066</ComponentLength> 
      </TrackSegment> 
      </TimelineTrack> 
     </PackageTracks> 
     <PackageName>Name001</PackageName> 
     <PackageID>urn:44f70006</PackageID> 
     </SourcePackage> 
     <CompositionPackage> 
     <PackageTracks> 
      <TimelineTrack> 
      <TrackSegment> 
       <SourcePackageID>urn:44f70006</SourcePackageID> 
       <ComponentLength>10099</ComponentLength> 
      </TrackSegment> 
      </TimelineTrack> 
     </PackageTracks> 
     <PackageName>NameABC</PackageName> 
     <PackageID>urn:ce1904fd</PackageID> 
     </CompositionPackage> 
     <CompositionPackage> 
     <PackageTracks> 
      <TimelineTrack> 
      <TrackSegment> 
       <SourcePackageID>urn:00f70009</SourcePackageID> 
       <ComponentLength>222</ComponentLength> 
      </TrackSegment> 
      </TimelineTrack> 
     </PackageTracks> 
     <PackageName>NameABC</PackageName> 
     <PackageID>urn:ff1603fd</PackageID> 
     </CompositionPackage> 
     <CompositionPackage> 
     <PackageTracks> 
      <TimelineTrack> 
      <TrackSegment> 
       <SourcePackageID>urn:11f80008</SourcePackageID> 
       <ComponentLength>444</ComponentLength> 
      </TrackSegment> 
      </TimelineTrack> 
     </PackageTracks> 
     <PackageName>NameBCD</PackageName> 
     <PackageID>urn:gg1702fj</PackageID> 
     </CompositionPackage> 
     <CompositionPackage> 
     <PackageTracks> 
      <TimelineTrack> 
      <TrackSegment> 
       <SourcePackageID>urn:22f90009</SourcePackageID> 
       <ComponentLength>555</ComponentLength> 
      </TrackSegment> 
      </TimelineTrack> 
     </PackageTracks> 
     <PackageName>NameXYZ</PackageName> 
     <PackageID>urn:11f80008</PackageID> 
     </CompositionPackage> 
     <MaterialPackage> 
     <PackageTracks> 
      <TimelineTrack> 
      <TrackSegment> 
      <ComponentLength>864</ComponentLength> 
      </TrackSegment> 
      </TimelineTrack> 
     </PackageTracks> 
     <PackageName>Name002</PackageName> 
     <PackageID>urn:00f70009</PackageID> 
     </MaterialPackage> 
    </ContentStorage> 
</Preface> 
</AAG> 

样品XSL:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="@*|node()"> 
<xsl:copy> 
<xsl:apply-templates select="@*|node()"/> 
</xsl:copy> 
</xsl:template> 

<xsl:template match = "AAG"> 
<Master> 
<xsl:for-each select="AAG/Preface/ContentStorage"> 
<newnode> 
    <value1><xsl:value-of select ="CompositionPackage/PackageTracks/TimelineTrack/TrackSegment/ComponentLength"/></value1> 
    <value2><xsl:value-of select ="CompositionPackage/PackageTracks/TimelineTrack/TrackSegment/SourcePackageID"/></value2> 
    <value3><xsl:value-of select ="CompositionPackage/PackageTracks/TimelineTrack/TrackSegment[SourcePackageID=current()/MaterialPackage/PackageName"/></value3> 
</newnode> 
</xsl:for-each> 
</Master> 
</xsl:template> 
</xsl:stylesheet> 

预期的XML:

<Master> 
<newnode> 
    <Value1>1099</Value1> 
    <Value2>urn:44f70006</Value2> 
    <Value3>Name001</Value3> 
</newnode> 
<newnode> 
    <Value1>222</Value1> 
    <Value2>urn:00f70009</Value2> 
    <Value3>Name002</Value3> 
</newnode> 
<newnode> 
    <Value1>444</Value1> 
    <Value2>urn:11f80008</Value2> 
    <Value3>NameXYZ</Value3> 
</newnode> 
<newnode> 
    <Value1>555</Value1> 
    <Value2>urn:22f90009</Value2> 
    <Value3></Value3> 
</newnode> 
</Master> 

我目前的XSL是 “回” 的所有值3元。

提供的转换有几个错误

下转型是提供一个与错误修正

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match = "AAG"> 
    <Master> 
    <xsl:for-each select="Preface/ContentStorage/CompositionPackage"> 
     <newnode> 
      <value1> 
       <xsl:value-of select= 
       "PackageTracks/TimelineTrack/TrackSegment/ComponentLength"/> 
      </value1> 
      <value2> 
      <xsl:value-of select= 
       "PackageTracks/TimelineTrack/TrackSegment/SourcePackageID"/> 
     </value2> 
      <value3> 
      <xsl:value-of select= 
       "../*[self::SourcePackage or self::MaterialPackage] 
           [PackageID 
           = 
           current() 
           /PackageTracks/TimelineTrack/TrackSegment/SourcePackageID 
           ] 
           /PackageName 
       "/> 
      </value3> 
     </newnode> 
    </xsl:for-each> 
    </Master> 
    </xsl:template> 
</xsl:stylesheet> 

当这种变换所提供的XML文档应用:

<AAG version="1.1"> 
    <Preface> 
     <ContentStorage> 
      <SourcePackage> 
       <PackageTracks> 
        <TimelineTrack> 
         <TrackSegment> 
          <ComponentLength>5066</ComponentLength> 
         </TrackSegment> 
        </TimelineTrack> 
       </PackageTracks> 
       <PackageName>Name001</PackageName> 
       <PackageID>urn:44f70006</PackageID> 
      </SourcePackage> 
      <CompositionPackage> 
       <PackageTracks> 
        <TimelineTrack> 
         <TrackSegment> 
          <SourcePackageID>urn:44f70006</SourcePackageID> 
          <ComponentLength>10099</ComponentLength> 
         </TrackSegment> 
        </TimelineTrack> 
       </PackageTracks> 
       <PackageName>NameABC</PackageName> 
       <PackageID>urn:ce1904fd</PackageID> 
      </CompositionPackage> 
      <CompositionPackage> 
       <PackageTracks> 
        <TimelineTrack> 
         <TrackSegment> 
          <SourcePackageID>urn:00f70009</SourcePackageID> 
          <ComponentLength>222</ComponentLength> 
         </TrackSegment> 
        </TimelineTrack> 
       </PackageTracks> 
       <PackageName>NameABC</PackageName> 
       <PackageID>urn:ff1603fd</PackageID> 
      </CompositionPackage> 
      <MaterialPackage> 
       <PackageTracks> 
        <TimelineTrack> 
         <TrackSegment> 
          <ComponentLength>864</ComponentLength> 
         </TrackSegment> 
        </TimelineTrack> 
       </PackageTracks> 
       <PackageName>Name002</PackageName> 
       <PackageID>urn:00f70009</PackageID> 
      </MaterialPackage> 
     </ContentStorage> 
    </Preface> 
</AAG> 

想要的,正确的结果产生

<Master> 
    <newnode> 
     <value1>10099</value1> 
     <value2>urn:44f70006</value2> 
     <value3>Name001</value3> 
    </newnode> 
    <newnode> 
     <value1>222</value1> 
     <value2>urn:00f70009</value2> 
     <value3>Name002</value3> 
    </newnode> 
</Master> 
+0

嗨Dimitre,谢谢。和预期的XML一样,我会认为value3的值是Name001。第一个CompositionPackage的packageID与第一个SourcePackage的PackageID匹配。其包名是Name001。我会用更多的信息更新这个问题。 – user1540142 2012-08-17 03:44:48

+0

@ user1540142,它实际上*是*'Name001' - 您可能已经看到此答案的早期版本 - 请刷新。 – 2012-08-17 03:52:11

+0

谢谢你DIMITRE:你是XSL向导!我需要刷新:) – user1540142 2012-08-17 03:53:42