<Data>
<Record Id="1826155" username="BobDylan" >
<ART id="121028890624">
<TYPE>Song</TYPE>
<AUTH>
<AUTHOR_ID>1826155</AUTHOR_ID>
<FNAME>Bob</FNAME>
<LNAME>Dylan</LNAME>
<HIDE/>
</AUTH>
<AUTH>
<AUTHOR_ID>175782</AUTHOR_ID>
<FNAME>Frank</FNAME>
<LNAME>Sinatra</LNAME>
<HIDE>true</HIDE>
</AUTH>
<STATUS>Published</STATUS>
<TITLE>A Cool Song </TITLE>
</ART>
<ART id="123840712342">
<TYPE>Song</TYPE>
<AUTH>
<AUTHOR_ID>1826155</AUTHOR_ID>
<FNAME>Bob</FNAME>
<LNAME>Dylan</LNAME>
<HIDE>true</HIDE>
</AUTH>
<AUTH>
<AUTHOR_ID>175782</AUTHOR_ID>
<FNAME>Tom</FNAME>
<LNAME>Waits</LNAME>
</AUTH>
<STATUS>Published</STATUS>
<TITLE>New Song</TITLE>
</ART>
<ART id="123840737280">
<TYPE>Book</TYPE>
<AUTH>
<AUTHOR_ID>1826155</AUTHOR_ID>
<FNAME>Bob</FNAME>
<LNAME>Dylan</LNAME>
<HIDE/>
</AUTH>
<AUTH>
<AUTHOR_ID>175782</AUTHOR_ID>
<FNAME>Tom</FNAME>
<LNAME>Wolfe</LNAME>
</AUTH>
<STATUS>Accepted</STATUS>
<TITLE>New Book</TITLE>
</ART>
</Record>
</Data>
我尝试通过选择符合以下条件的Song节点来转换上述XML:
所需的XML输出应包括Type,所有作者和标题。第二个歌曲类型在此示例中隐藏(因为主要作者的HIDE = true):
<h3>Songs</h3>
<div>
<ul>
<li>Bob Dylan, Frank Sinatra; A Cool Song</li>
</ul>
</div>
我开始尝试每个人,但发现我无法处理与Record Id不匹配的作者。根据建议,我相信这是使用模板最好的。我有一些XSLT无法正常工作,而是显示所有数据而不是子集。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="html" encoding="utf-8" />
<xsl:variable name="userId" select="dm:Data/dm:Record/@userId"/>
<xsl:template match="/Data/Record/ART[TYPE='Song']">
<xsl:apply-templates select= "/Data/Record/ART[CONTYPE='Song']/AUTH[AUTHOR_ID = $userId]" />
</xsl:template>
<xsl:template match="/Data/Record/ART[TYPE='Song']">
<xsl:apply-templates select= "/Data/Record/ART[TYPE='Song']/AUTH[/STATUS = 'PUBLISHED']" />
</xsl:template>
<xsl:template match="/Data/Record/ART[TYPE='Song']">
<xsl:value-of select="./FNAME"/> <xsl:text> </xsl:text>
<xsl:value-of select="./LNAME"/> <xsl:text> </xsl:text>
<xsl:value-of select="./TITLE"/> <xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
我开始尝试每个人,但发现我无法应对 显示与记录ID不匹配的作者。
为什么不呢?
<xsl:for-each select="/Data/Record/ART/AUTH[AUTHOR_ID = ancestor::Record/@Id]">
将仅选择AUTHOR_ID与其记录的ID匹配的作者。
要将其缩小为仅发布歌曲的作者,您可以使用:
<xsl:for-each select="/Data/Record/ART[TYPE = 'Song' and STATUS = 'Published']/AUTH[AUTHOR_ID = ancestor::Record/@Id]">
进一步排除隐藏的作者:
<xsl:for-each select="/Data/Record/ART[TYPE = 'Song' and STATUS = 'Published']/AUTH[AUTHOR_ID = ancestor::Record/@Id and not(HIDE='true')]">
当然,您也可以在xsl:apply-templates
使用相同的谓词。
响应您的修改:
我仍然觉得这些要求令人困惑。我想你想做这样的事情:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/Data">
<h3>Songs</h3>
<div>
<xsl:for-each select="Record/ART[TYPE = 'Song' and STATUS = 'Published' and not(parent::Record/@Id = AUTH[HIDE='true']/AUTHOR_ID)]">
<ul>
<li>
<xsl:for-each select="AUTH">
<xsl:value-of select="FNAME"/>
<xsl:text> </xsl:text>
<xsl:value-of select="LNAME"/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>; </xsl:text>
<xsl:value-of select="TITLE"/>
</li>
</ul>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
这将选择满足所有这些条件的每种ART:
TYPE =&#39; Song&#39 ;;
状态=&#39;已发布&#39;;
它的作者都没有(a)AUTHOR_ID与祖先的记录ID 匹配和(b)HIDE =&#39; True&#39;。< / p>
对于每一个这样的ART,它的所有作者都会被列出,以及ART的标题:
<强>结果强>
<h3>Songs</h3><div>
<ul>
<li>Bob Dylan, Frank Sinatra; A Cool Song </li>
</ul>
</div>
答案 1 :(得分:1)
这应该有用。
第一个匹配找到记录并将id存储在recId变量中。然后,它使用此变量将ART上的匹配应用于您指定的id和其他参数。您提供的示例XML没有名称空间,因此我将其关闭。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="html" encoding="utf-8" />
<xsl:template match="/Data/Record">
<xsl:variable name="recId" select="@Id"/>
<xsl:apply-templates select="ART[TYPE='Song' and STATUS='Published' and AUTH/AUTHOR_ID=$recId and AUTH/HIDE!='true']" />
</xsl:template>
<xsl:template match="Data/Record/ART">
<xsl:value-of select="TITLE"/>
<xsl:value-of select="AUTH/FNAME"/>
<xsl:value-of select="AUTH/LNAME"/>
</xsl:template>
</xsl:stylesheet>