解析不存在的XML标记

时间:2014-07-24 09:32:57

标签: xml xslt latex

这个问题是对this one的跟进。我正在编写一个XSLT脚本来将XML转换为LaTeX。下面是一个示例XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<lin ryk="ind">A paragraph with short indentation.</lin>
<lin ryk="ind2">A paragraph with long indentation.</lin>

<blok ryk="udspark">
<lin>
<tab ryk="ind">Text on the left.</tab>
<tab>Text on the right.</tab>
</lin>
</blok>

长话短说,<blok ryk="udspark">标记会在左侧写入第一个<tag>的内容,在右侧写入第二个<tag>的内容,以空格分隔(这是在LaTeX中通过使用命令\hfill)分离它们完成的。换句话说,我想解析上面的<blok ryk="udspark">标记,好像实际上是

<lin ryk="ind">Text on the left.\hfill Text on the right.</lin>

请注意,第一个标签的"ind"属性的值@ryk已解析为<lin>。通常,对于X的任何值,我想要

<blok ryk="udspark">
<lin>
<tab ryk="X">Text on the left.</tab>
<tab>Text on the right.</tab>
</lin>
</blok>

被解析为

<lin ryk="X">Text on the left.\hfill Text on the right.</lin>

由于我之前链接的问题,我尝试了以下代码(如果您不了解LaTeX,请不要过于担心<lin>标签的定义。他们确实注意到了很多;重要的是<blok ryk="udspark">):

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" encoding="UTF-8"/>

<xsl:template match="/">

\documentclass{memoir}

\begin{document}

<xsl:apply-templates/>

</xsl:template>

<xsl:template match="lin[@ryk='ind']">
\indent <xsl:apply-templates/><xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="lin[@ryk='ind2']">
\hangpara{2\parindent}{-1}{<xsl:apply-templates/>}<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="blok[@ryk='udspark']">
<xsl:variable name="l2">
<lin ryk="lin/tab[1]/@ryk">
<xsl:copy-of select="node()/lin/tab[1]"/>\hfill <xsl:copy-of select="node()/lin/tab[2]"/></lin>
</xsl:variable>
<xsl:apply-templates select="$l2/node()"/>
</xsl:template>

然而,它不起作用!唯一出现的是\hfill,没有别的。

请注意,在我的真实文档中,X可以使(!!!)的值多于上述值。这就是为什么我想重用<lin>标签的XSLT代码,而不是仅仅在<blok ryk="udspark">标签的代码中再次编程。

1 个答案:

答案 0 :(得分:2)

而不是<lin ryk="lin/tab[1]/@ryk">,而不是<lin ryk="{lin/tab[1]/@ryk}">,它将使用花括号中的XPath表达式的结果填充属性。

然后对于内容而不是<xsl:copy-of select="node()/lin/tab[1]"/>\hfill <xsl:copy-of select="node()/lin/tab[2]"/></lin>,我认为您需要<xsl:value-of select="lin/tab[1]"/>\hfill <xsl:value-of select="lin/tab[2]"/></lin>

所以完整的代码将是

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" encoding="UTF-8"/>

<xsl:template match="/">

\documentclass{memoir}

\begin{document}

<xsl:apply-templates/>

</xsl:template>

<xsl:template match="lin[@ryk='ind']">
\indent <xsl:apply-templates/><xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="lin[@ryk='ind2']">
\hangpara{2\parindent}{-1}{<xsl:apply-templates/>}<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="blok[@ryk='udspark' and lin/tab/@ryk]">
<xsl:variable name="l2">
<lin ryk="{lin/tab[1]/@ryk}">
<xsl:value-of select="lin/tab[1]"/>\hfill <xsl:value-of select="lin/tab[2]"/></lin>
</xsl:variable>
<xsl:apply-templates select="$l2/node()"/>
</xsl:template>

</xsl:stylesheet>

转换

<root>
<lin ryk="ind">A paragraph with short indentation.</lin>
<lin ryk="ind2">A paragraph with long indentation.</lin>

<blok ryk="udspark">
<lin>
<tab ryk="ind">Text on the left.</tab>
<tab>Text on the right.</tab>
</lin>
</blok>
</root>

\documentclass{memoir}

\begin{document}



\indent A paragraph with short indentation.


\hangpara{2\parindent}{-1}{A paragraph with long indentation.}



\indent Text on the left.\hfill Text on the right.