解析不存在的 XML 标记



这个问题是这个问题的后续问题。我正在编写一个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>

注意,第一个选项卡的@ryk属性的"ind"值被解析为<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{2parindent}{-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">标记的代码中重新编程。

您希望用<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{2parindent}{-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{2parindent}{-1}{A paragraph with long indentation.}

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

最新更新