我有以下XML示例,我需要一些帮助。
示例XML具有所需的PackageID和SourcePackageID值
匹配其他节点以查找我之后的结果。
我事先道歉,这让我很难解释。
如果您需要更多信息来了解这一点,请告诉我。 :)
所需的结果是为CompositionPackage中的Usage元素为“TopLevel”的每个Source元素找到MaterialPackage匹配。
有些结果更容易找到,因为它们是一场比赛。其他人虽然需要通过多个匹配来循环才能找到结果。
例如:结果/ Name元素引用具有匹配PackageID的CompositionPackage的PackageName。 但是:result / Source元素需要引用匹配的CompositionPackage的SourcePackageID,然后使用其PackageID查找Material Package的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>
答案 0 :(得分:1)
解决此问题的一种方法是使用 xsl:key 来查找 CompositionPackage 和 MaterialPackage 元素,方法是包ID
<xsl:key name="CompositionPackage" match="CompositionPackage" use="PackageID"/>
<xsl:key name="MaterialPackage" match="MaterialPackage" use="PackageID"/>
然后,假设您定位在“顶级”来源元素上,您首先要为包选择相关的 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 ,模板将以递归方式匹配自身。但是对于 MatertialPackage ,您只需输出包名称。
这是完整的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>