0

次の XML の例がありますが、これについては助けが必要です。サンプル XML には PackageID と SourcePackageID の値が含まれており、これらの値を他のノードと照合して目的の結果を見つける必要があります。
これについての事前の謝罪は、私が説明するのを非常に混乱させます。これを理解するためにさらに情報が必要な場合はお知らせください。:)

必要な結果は、Usage 要素が「TopLevel」である CompositionPackage 内の各 Source 要素に一致する MaterialPackage を見つけることです。

一部の結果は、あと 1 試合であるため、簡単に見つけることができます。ただし、結果を見つけるために複数の一致をループする必要があるものもあります。

例: 結果の /Name 要素は、一致する PackageID を持つ CompositionPackage の PackageName を参照します。ただし、結果の /Source 要素は、一致する CompositionPackage の SourcePackageID を参照し、その PackageID を使用してマテリアル パッケージの PackageName を見つける必要があります。

ある例では、CompositionPackage/SourcePackageID は直接 MaterialPackage を参照します。ただし、CompositionPackage の /Operation 値が「RepeatTransfer」である場合、MaterialPackage にリンクする前に別の CompositionPackage が参照されます。うーん

どんな助けでも本当に感謝します。

サンプル入力 XML:

<AAG version="1.1">
<Preface>
<ContentStorage>
  <MaterialPackage>
    <PackageTracks>
      <TimelineTrack>
        <TrackSegment>
            <ComponentLength>5066</ComponentLength>
        </TrackSegment>
      </TimelineTrack>
    </PackageTracks>
    <PackageName>Tape011</PackageName>
    <PackageID>urn:MM111</PackageID>
  </MaterialPackage>
  <CompositionPackage>
    <PackageTracks>
      <TimelineTrack>
        <TrackSegment>
            <SourcePackageID>urn:MM111</SourcePackageID>
            <ComponentLength>10099</ComponentLength>
        </TrackSegment>
      </TimelineTrack>
    </PackageTracks>
    <Operation>Transfer</Operation>
    <PackageName>NameABC</PackageName>
    <PackageID>urn:CC111</PackageID>
  </CompositionPackage>
  <CompositionPackage>
    <PackageTracks>
      <TimelineTrack>
        <TrackSegment>
            <SourcePackageID>urn:CC333</SourcePackageID>
            <ComponentLength>222</ComponentLength>
        </TrackSegment>
      </TimelineTrack>
    </PackageTracks>
    <Operation>RepeatTransfer</Operation>
    <PackageName>NameBCD</PackageName>
    <PackageID>urn:CC222</PackageID>
  </CompositionPackage>
  <CompositionPackage>
    <PackageTracks>
      <TimelineTrack>
        <TrackSegment>
            <SourcePackageID>urn:MM222</SourcePackageID>
            <ComponentLength>444</ComponentLength>
        </TrackSegment>
      </TimelineTrack>
    </PackageTracks>
    <Operation>Transfer</Operation>
    <PackageName>NameCDE</PackageName>
    <PackageID>urn:CC333</PackageID>
  </CompositionPackage>
  <CompositionPackage>
    <PackageTracks>
      <TimelineTrack>
        <TrackSegment>
            <SourcePackageID>urn:MM333</SourcePackageID>
            <ComponentLength>555</ComponentLength>
        </TrackSegment>
      </TimelineTrack>
    </PackageTracks>
    <Operation>Transfer</Operation>
    <PackageName>NameDEF</PackageName>
    <PackageID>urn:CC444</PackageID>
  </CompositionPackage>
  <MaterialPackage>
    <PackageTracks>
      <TimelineTrack>
        <TrackSegment>
        <ComponentLength>864</ComponentLength>
        </TrackSegment>
      </TimelineTrack>
    </PackageTracks>
    <PackageName>Tape012</PackageName>
    <PackageID>urn:MM222</PackageID>
  </MaterialPackage>
  <MaterialPackage>
    <PackageTracks>
      <TimelineTrack>
        <TrackSegment>
        <ComponentLength>864</ComponentLength>
        </TrackSegment>
      </TimelineTrack>
    </PackageTracks>
    <PackageName>Tape013</PackageName>
    <PackageID>urn:MM333</PackageID>
  </MaterialPackage>
  <CompositionPackage>
    <PackageTracks>
      <TimelineTrack>
        <TrackSegment>
            <Sequence>
                <Source>
                    <SourcePackageID>urn:CC111</SourcePackageID>
                </Source>
                <Source>
                    <SourcePackageID>urn:CC222</SourcePackageID>
                </Source>
                <Unknown>urn:0000</Unknown>
                <Source>
                    <SourcePackageID>urn:CC444</SourcePackageID>
                </Source>
            </Sequence>
        </TrackSegment>
      </TimelineTrack>
    </PackageTracks>
    <Usage>TopLevel</Usage>
    <Operation>Transfer</Operation>
    <PackageName>NameXXX</PackageName>
    <PackageID>urn:CCXXX</PackageID>
  </CompositionPackage>
</ContentStorage>
</Preface>
</AAG>

予期される出力 XML:

<AAG>
<Preface>
    <Book>
        <Name>NameABC</Name>
        <Source>Tape011</Source>
    </Book>
    <Book>
        <Name>NameBCD</Name>
        <Source>Tape012</Source>
    </Book>
    <Book>
        <Name>NameDEF</Name>
        <Source>Tape013</Source>
    </Book>
</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">

<AAG>
<Preface>
    <xsl:for-each select="/AAG/Preface/ContentStorage/CompositionPackage/PackageTracks/TimelineTrack/TrackSegment/Sequence[../../../../Usage='TopLevel']">

    <xsl:choose>
        <xsl:when test = "self::Source">
            <Book>
                <Name><xsl:value-of select="../../../../*[self::CompositionPackage or self::MaterialPackage]
                                                            [PackageID=current()
                                                            /SourcePackageID]/PackageName"/></Name>

                <!-- cant work out how to do this bit 
                                    need to find MaterialPackage/PackageName from a CompositionPackage that in turn references another CompositionPackage that in turn references the MaterialPackage. -->
                                    <xsl:choose>
                <xsl:when test = "CompositionPackage[Operation='RepeatTransfer']">
                <Source><xsl:value-of select="../../../../*[self::CompositionPackage or self::MaterialPackage]
                                                            [PackageID=current()
                                                            /SourcePackageID]/PackageName"/></Source>
                </xsl:when>
                <xsl:otherwise>
                <Source><xsl:value-of select="../../../../*[self::CompositionPackage or self::MaterialPackage]
                                                            [PackageID=current()
                                                            /SourcePackageID]/PackageName"/></Source>
                </xsl:otherwise>
                </xsl:choose>
            </Book>
        </xsl:when>

    </xsl:choose>
    </xsl:for-each>

</Preface>
</AAG>

</xsl:template>

4

1 に答える 1

1

これにアプローチする 1 つの方法は、xsl:keyを使用して、PackageID を介してCompositionPackage要素とMaterialPackage要素を検索することです。

<xsl:key name="CompositionPackage" match="CompositionPackage" use="PackageID"/>
<xsl:key name="MaterialPackage" match="MaterialPackage" use="PackageID"/>

次に、「トップレベル」のSource要素に配置されていると仮定すると、パッケージに関連するCompositionPackageを選択することから始めます。

<xsl:apply-templates select="key('CompositionPackage', SourcePackageID)" mode="Source" />

モードの使用に注意してください。結果の xslt には、 CompositionPackage要素に一致する複数のテンプレートが存在するため、これが必要になります。ただし、最初のテンプレート内では、Book要素を出力することから始めます。

<xsl:template match="CompositionPackage" mode="Source">
   <Book>
      <Name><xsl:value-of select="PackageName" /></Name>
      <Source><xsl:apply-templates select="." /></Source>
   </Book>
</xsl:template>

*Source要素については、潜在的に再帰的なルックアップを開始します。CompositionPackage要素に一致する別のテンプレートがありますが、このテンプレートでは、パッケージが別のCompositionPackageまたはMaterialPackage内にあるかどうかを確認します。これはキーを利用します

<xsl:template match="CompositionPackage">
  <xsl:apply-templates select="
    key('MaterialPackage',PackageTracks/TimelineTrack/TrackSegment/SourcePackageID)
    |key('CompositionPackage', PackageTracks/TimelineTrack/TrackSegment/SourcePackageID)"/>
</xsl:template>

それがCompositionPackageの場合、テンプレートは再帰的にそれ自体に一致します。ただし、MaterialPackageの場合は、パッケージ名を出力するだけです。

ここに完全な XSLT があります

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="CompositionPackage" match="CompositionPackage" use="PackageID"/>
   <xsl:key name="MaterialPackage" match="MaterialPackage" use="PackageID"/>

   <xsl:template match="/AAG">
      <AAG>
         <Preface>
            <xsl:apply-templates select="Preface/ContentStorage/CompositionPackage[Usage='TopLevel']/PackageTracks/TimelineTrack/TrackSegment/Sequence/Source"/>
         </Preface>
      </AAG>
   </xsl:template>

   <xsl:template match="Source">
      <xsl:apply-templates select="key('CompositionPackage', SourcePackageID)" mode="Source" />
   </xsl:template>

   <xsl:template match="CompositionPackage" mode="Source">
      <Book>
         <Name><xsl:value-of select="PackageName" /></Name>
         <Source>
            <xsl:apply-templates select="." />
         </Source>
      </Book>
   </xsl:template>

   <xsl:template match="CompositionPackage">
      <xsl:apply-templates select="key('MaterialPackage', PackageTracks/TimelineTrack/TrackSegment/SourcePackageID)|key('CompositionPackage', PackageTracks/TimelineTrack/TrackSegment/SourcePackageID)"/>
   </xsl:template>

   <xsl:template match="MaterialPackage">
      <xsl:value-of select="PackageName" />
   </xsl:template>   

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

XSLT に適用すると、次のように出力されます。

<AAG>
   <Preface>
      <Book>
         <Name>NameABC</Name>
         <Source>Tape011</Source>
      </Book>
      <Book>
         <Name>NameBCD</Name>
         <Source>Tape012</Source>
      </Book>
      <Book>
         <Name>NameDEF</Name>
         <Source>Tape013</Source>
      </Book>
   </Preface>
</AAG>
于 2012-08-25T09:34:14.507 に答える