XSLT 转换替换文档中定期出现的标签
我有一个 xml 文档,我正在使用 xslt 将其转换为 xsl-fo 文档。我有这个棘手的问题,我长期以来一直在尝试寻找解决方案......
在我的源 xml 中,我散布着一些标签。我想在结果文档中将它们格式化为下划线,但是我无法这样做。
我正在尝试使用这样的代码:
<xsl:template match="//em">
<fo:inline text-decoration="underline">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
完整的 XSLT 如下所示:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<!-- match em tags -->
<xsl:template match="//em">
<fo:inline text-decoration="underline">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<xsl:template match="//u">
<fo:inline text-decoration="underline">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<!-- match b tags -->
<xsl:template match="//b">
<fo:inline font-weight="bold">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<xsl:template match="//br">
<fo:block><xsl:text>
</xsl:text></fo:block>
</xsl:template>
<xsl:template match="briefs">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="Evidence" page-width="8.5in" page-height="11in" margin="1in">
<fo:region-body margin-bottom=".5in" margin-top=".5in" region-name="xsl-region-body" />
<fo:region-before extent="1em" region-name="xsl-region-before" />
<fo:region-after extent="1em" region-name="xsl-region-after" />
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:for-each select="brief">
<fo:page-sequence master-reference="Evidence">
<fo:static-content flow-name="xsl-region-before" font-family="Times">
<fo:block font-size="10pt" text-align="center" color="#666666">
<fo:inline font-style="italic"><xsl:value-of select="title"/></fo:inline> by <xsl:value-of select="author"/>
</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after" font-family="Times" font-size="10pt">
<fo:table>
<fo:table-column />
<fo:table-column column-width="1in" />
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block text-align="left" color="#666"><xsl:value-of select="copyright"/></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block text-align="right" font-weight="bold">
Page <fo:page-number/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:static-content>
<fo:flow flow-name="xsl-region-body" font-family="Times">
<fo:block font-size="14pt" text-align="center" text-transform="uppercase" border-before-width="2pt" border-before-color="black" border-before-style="double" border-after-width="1pt" border-after-color="black" border-after-style="solid" background-color="#ccc">
<xsl:value-of select="title"/>
</fo:block>
<xsl:for-each select="heading">
<xsl:choose>
<xsl:when test="@level = 2">
<fo:block font-size="11pt" font-weight="bold" keep-with-next="always" text-transform="uppercase" padding-before="1em">
<xsl:value-of select="title"/></fo:block>
</xsl:when>
<xsl:when test="@level = 3">
<fo:block font-size="10pt" font-weight="normal" keep-with-next="always" text-transform="uppercase" padding-before="1em">
<xsl:value-of select="title"/></fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block font-size="12pt" font-weight="bold" keep-with-next="always" text-transform="uppercase" padding-before="1em">
<xsl:value-of select="title"/></fo:block>
</xsl:otherwise>
</xsl:choose>
<xsl:for-each select="content/item">
<xsl:choose>
<xsl:when test="@type = 'card'">
<!--Print the taglines-->
<fo:block font-size="10pt" font-weight="bold" padding-before="1em" keep-with-next="always">
<!--<xsl:number value="position()" format="1" />. -->
<xsl:value-of select="tagline"/>
</fo:block>
<!--Print the citation-->
<fo:block font-size="10pt" font-style="italic" keep-with-next="always" keep-together.within-page="always" margin-left=".25in" padding-before=".5em">
<!--<xsl:number value="position()" format="1" />. -->
<xsl:value-of select="citation" disable-output-escaping="yes" />
</fo:block>
<!--Print the body-->
<fo:block font-size="10pt" keep-together.within-page="always" margin-left=".25in" padding-before=".5em">
<!--<xsl:number value="position()" format="1" />. -->
<xsl:value-of select="quote" disable-output-escaping="yes" />
</fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block font-size="10pt" padding-before=".5em"><xsl:value-of select="."/></fo:block>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:for-each>
</fo:root>
</xsl:template>
</xsl:stylesheet>
有人有什么想法吗? 非常感谢!!!!!
I have an xml document that I am transforming with xslt into an xsl-fo document. I have this tricky problem I've been trying to track down a solution to for a long time...
In my source xml I have a few tags interspersed throughout. I want to format these as underline in the resulting document, however I have not been able to do so.
I'm trying using code like this:
<xsl:template match="//em">
<fo:inline text-decoration="underline">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
The full XSLT looks like this:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<!-- match em tags -->
<xsl:template match="//em">
<fo:inline text-decoration="underline">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<xsl:template match="//u">
<fo:inline text-decoration="underline">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<!-- match b tags -->
<xsl:template match="//b">
<fo:inline font-weight="bold">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:template>
<xsl:template match="//br">
<fo:block><xsl:text>
</xsl:text></fo:block>
</xsl:template>
<xsl:template match="briefs">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="Evidence" page-width="8.5in" page-height="11in" margin="1in">
<fo:region-body margin-bottom=".5in" margin-top=".5in" region-name="xsl-region-body" />
<fo:region-before extent="1em" region-name="xsl-region-before" />
<fo:region-after extent="1em" region-name="xsl-region-after" />
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:for-each select="brief">
<fo:page-sequence master-reference="Evidence">
<fo:static-content flow-name="xsl-region-before" font-family="Times">
<fo:block font-size="10pt" text-align="center" color="#666666">
<fo:inline font-style="italic"><xsl:value-of select="title"/></fo:inline> by <xsl:value-of select="author"/>
</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after" font-family="Times" font-size="10pt">
<fo:table>
<fo:table-column />
<fo:table-column column-width="1in" />
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block text-align="left" color="#666"><xsl:value-of select="copyright"/></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block text-align="right" font-weight="bold">
Page <fo:page-number/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:static-content>
<fo:flow flow-name="xsl-region-body" font-family="Times">
<fo:block font-size="14pt" text-align="center" text-transform="uppercase" border-before-width="2pt" border-before-color="black" border-before-style="double" border-after-width="1pt" border-after-color="black" border-after-style="solid" background-color="#ccc">
<xsl:value-of select="title"/>
</fo:block>
<xsl:for-each select="heading">
<xsl:choose>
<xsl:when test="@level = 2">
<fo:block font-size="11pt" font-weight="bold" keep-with-next="always" text-transform="uppercase" padding-before="1em">
<xsl:value-of select="title"/></fo:block>
</xsl:when>
<xsl:when test="@level = 3">
<fo:block font-size="10pt" font-weight="normal" keep-with-next="always" text-transform="uppercase" padding-before="1em">
<xsl:value-of select="title"/></fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block font-size="12pt" font-weight="bold" keep-with-next="always" text-transform="uppercase" padding-before="1em">
<xsl:value-of select="title"/></fo:block>
</xsl:otherwise>
</xsl:choose>
<xsl:for-each select="content/item">
<xsl:choose>
<xsl:when test="@type = 'card'">
<!--Print the taglines-->
<fo:block font-size="10pt" font-weight="bold" padding-before="1em" keep-with-next="always">
<!--<xsl:number value="position()" format="1" />. -->
<xsl:value-of select="tagline"/>
</fo:block>
<!--Print the citation-->
<fo:block font-size="10pt" font-style="italic" keep-with-next="always" keep-together.within-page="always" margin-left=".25in" padding-before=".5em">
<!--<xsl:number value="position()" format="1" />. -->
<xsl:value-of select="citation" disable-output-escaping="yes" />
</fo:block>
<!--Print the body-->
<fo:block font-size="10pt" keep-together.within-page="always" margin-left=".25in" padding-before=".5em">
<!--<xsl:number value="position()" format="1" />. -->
<xsl:value-of select="quote" disable-output-escaping="yes" />
</fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block font-size="10pt" padding-before=".5em"><xsl:value-of select="."/></fo:block>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:for-each>
</fo:root>
</xsl:template>
</xsl:stylesheet>
Does anyone have any ideas?
Thanks so much!!!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不清楚你的代码在哪里真正“疯狂”地处理文档 - 即运行匹配。如果
是根节点,那么我希望在某些位置看到一些
或类似的内容观点;否则,您将仅获得根匹配中指定的输出(并且它永远不会应用您的等匹配)。
如果您只想在定义时使用替换来处理整个文档,那么经典匹配类似于:
因为它匹配所有节点并级联,所以它会针对每个节点运行,直到找到更具体的匹配。因此,对于 xslt:
大多数节点将“按原样”重复,但任何
元素都将替换为
(并且没有任何属性/内容)。请注意,即使这样;如果您希望通过匹配来处理子数据,则您需要显式级联(如上面的
示例所示,而不需要)强>级联)。而且我在您的
匹配中看不到任何
。最后;
match="//em"
是多余的;match="em"
应该足够了。It isn't clear to me where your code is to actually "go wild" with the document - i.e. run the matches. If
<briefs>
is the root node, then I would expect to see some<xsl:apply-templates select="*"/>
or similar at some point; otherwise you are only going to get the output as specified in the root match (and it will never apply your<em>
etc matches).If you want to process the entire document using substitutions only when defined, then the classic match is something like:
Because this matches all nodes, and cascades, it runs for every node until a more specific match is found. So with the xslt:
Most nodes will be repeated "as is", but any
<bar>
elements will be replaced with<BAR/>
(and without any attributes/content).Note that even with this; you need to explicitly cascade if you expect child data to be processed by matches (as shown by the
<bar>
example above, which doesn't cascade). And I can't see any<xsl:apply-templates>
in your<briefs>
match.Finally; the
match="//em"
is redundant;match="em"
should suffice.看不到整个样式表并没有帮助,但匹配语法可能应该是
match="em"
而不是match="//em"
。Not seeing the whole stylesheet doesn't help, but the match syntax should probably be
match="em"
notmatch="//em"
.看起来您是在命令式而不是声明式地执行 XSLT。 MG 是正确的,我认为如果你少做“
for-each
”,多做“apply-templates
”,你会更幸运。看起来您没有匹配所有 em 节点,因为您没有在主根模板中应用模板。我很想说,每个有 for-each 的地方,您可能应该使用 apply-templates 来代替,但这有点学术化。
It seems like you are doing your XSLT imperitively instead of declaratively. MG is correct, I think you'll have more luck if you do less "
for-each
"-ing and more "apply-templates
"-ing.It looks like you aren't matching all your em nodes because you aren't applying the templates inside your master root template. I'm tempted to say that every place you have a for-each, you should probably be using an apply-templates instead, but that's a bit academic.