我有一个代表文章的XML文件。我正在使用客户端xslt将其转换为html进行显示。
我试图在整个xml文件中嵌入引用,其中许多引用重复。我想知道我是否可以将引用从xml文件的内容部分中分离出来然后将它们链接在一起,这样我就不会重复多次了。
我认为我可以将ID和IDREF作为属性添加到<p>
和<reference>
标记中(使用XML Schema作为名称空间将在以后很重要)。因此:
<article>
<body>
<content>
<p>This is the first paragraph.</p>
<reference>Patrick</reference>
<content>
</content>
<p>This is the second paragraph and a lovely one it is too.</p>
<reference>Donald</reference>
<content>
</content>
<p>This paragraph uses the same reference as paragraph 1.</p>
<reference>Patrick</reference>
</content>
</body>
</article>
......会变成......
<article>
<body>
<p IDREF="ref1">This is the first paragraph.</p>
<p IDREF="ref2">This is the second paragraph and a lovely one it is too.</p>
<p IDREF="ref1">This paragraph uses the same reference as paragraph 1.</p>
</body>
<references>
<reference ID="#ref1">Patrick</reference>
<reference ID="#ref2">Donald</reference>
</references>
</article>
到目前为止,我失败了。我是在正确的轨道上吗?
答案 0 :(得分:1)
我会编写像
这样的模板<xsl:template match="body">
<xsl:copy>
<xsl:apply-templates select="content/p"/>
</xsl:copy>
<references>
<xsl:apply-templates select="content/reference"/>
</references>
</xsl:template>
<xsl:template match="p">
<p id="{generate-id()}">
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="reference">
<reference idref="#{generate-id(preceding-sibling::p[1])}">
<xsl:apply-templates/>
</reference>
</xsl:template>
或者,如果需要,您可以使用模式两次处理p
元素。如果需要,那么当然不是使用generate-id
,而是使用xsl:number
或count
生成自己的ID。
答案 1 :(得分:1)
我认为你想要这样的东西(没有彻底测试过):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kRef" match="reference" use="." />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/article" >
<xsl:copy>
<xsl:apply-templates/>
<references>
<xsl:apply-templates select="//reference[count(. | key('kRef', .)[1]) = 1]" mode="index"/>
</references>
</xsl:copy>
</xsl:template>
<xsl:template match="p">
<xsl:variable name="myRef" select="following-sibling::reference[1]" />
<xsl:copy>
<xsl:attribute name="IDREF">
<xsl:value-of select="count(key('kRef', $myRef)[1]/preceding::reference)+1" />
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="reference"/>
<xsl:template match="reference" mode="index">
<xsl:copy>
<xsl:attribute name="ID">
<xsl:value-of select="count(preceding::reference)+1" />
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果,使用您的样本输入:
<?xml version="1.0" encoding="utf-8"?>
<article>
<body>
<content>
<p IDREF="1">This is the first paragraph.</p>
<content/>
<p IDREF="2">This is the second paragraph and a lovely one it is too.</p>
<content/>
<p IDREF="1">This paragraph uses the same reference as paragraph 1.</p>
</content>
</body>
<references>
<reference ID="1">Patrick</reference>
<reference ID="2">Donald</reference>
</references>
</article>
以上是上述的修改版本,使用自动生成的ID来索引引用,而不是计算以前的出现次数:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kRef" match="reference" use="." />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/article" >
<xsl:copy>
<xsl:apply-templates/>
<references>
<xsl:apply-templates select="//reference[count(. | key('kRef', .)[1]) = 1]" mode="index"/>
</references>
</xsl:copy>
</xsl:template>
<xsl:template match="p">
<xsl:variable name="myRef" select="following-sibling::reference[1]" />
<xsl:copy>
<xsl:attribute name="IDREF">
<xsl:value-of select="generate-id(key('kRef', $myRef)[1])" />
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="reference"/>
<xsl:template match="reference" mode="index">
<xsl:copy>
<xsl:attribute name="ID">
<xsl:value-of select="generate-id(.)" />
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这里的结果看起来像(取决于处理器):
<?xml version="1.0" encoding="utf-8"?>
<article>
<body>
<content>
<p IDREF="idm758912">This is the first paragraph.</p>
<content/>
<p IDREF="idm251232">This is the second paragraph and a lovely one it is too.</p>
<content/>
<p IDREF="idm758912">This paragraph uses the same reference as paragraph 1.</p>
</content>
</body>
<references>
<reference ID="idm758912">Patrick</reference>
<reference ID="idm251232">Donald</reference>
</references>
</article>