XSLT 中的兄弟选择问题
Issues with sibling selection in XSLT
所以,我有一份 XML 文档,大致如下所示:
<root>
<section>
<text>A</text>
<alt>
<text>1</text>
</alt>
<text>B</text>
<nest>
<text>C</text>
<alt>
<text>3</text>
</alt>
<text>D</text>
</nest>
<text>E</text>
<alt>
<text>4</text>
<text>5</text>
</alt>
</section>
</root>
我 运行 遇到的具体问题是 alt
标签。 alt
标签中的 text
标签是前一个兄弟的属性。
为了清楚起见,我想要的输出是这样的:
[
{"text": "A", "alternate": "1"},
{"text": "B"},
{"text": "C", "alternate": "3"},
{"text": "D"},
{"text": "E", "alternate": "4;5"}
]
也就是说,虽然nest
标签存在,但它的作用基本为空。我已经使用下面的 XSLT 脚本完成了大部分转换:
<xsl:template match="root">
<xsl:text>[</xsl:text>
<xsl:apply-templates select=".//section/item|.//section/nest/item"/>
<xsl:text>]</xsl:text>
</xsl:template>
<xsl:template match="section/item|section/nest/item">
<xsl:text>{</xsl:text>
<xsl:text>"text":"</xsl:text>
<xsl:value-of select="current()"/>
<xsl:text>"</xsl:text>
<xsl:if test="following-sibling::alt">
<xsl:text>, "alternate":"</xsl:text>
<xsl:apply-templates select="alt"/>
<xsl:text>"</xsl:text>
</xsl:if>
<xsl:text>}</xsl:text>
<xsl:if test="position() != last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="alt">
<xsl:for-each select="text">
<xsl:value-of select="current()"/>
<xsl:if test="position() != last()">
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
它运行,但实际上不识别 alt
元素。我假设这个测试有一些问题:<xsl:if test="following-sibling::alt">
不太正确,但我想不通以挽救我的生命。
我已经尝试过其他一些分组,但这是我能使用的最接近的版本。我主要是想弄清楚如何让这个兄弟测试和遍历工作正常进行,但是我在 XSLT 方面的专业知识水平很低,所以我可能只是从错误的角度来处理事情。
首选 XSLT 1.0。
您的 XSLT 与示例 XML 输入不匹配。给定示例输入,可以使用以下方法实现所需的输出:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/root">
<xsl:text>[</xsl:text>
<xsl:apply-templates/>
<xsl:text> ]</xsl:text>
</xsl:template>
<xsl:template match="text">
<xsl:text> 	{"text":"</xsl:text>
<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
<xsl:apply-templates select="following-sibling::*[1][self::alt]" mode="alt"/>
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:template match="alt" mode="alt">
<xsl:text>, "alternate":"</xsl:text>
<xsl:apply-templates mode="alt"/>
<xsl:text>"</xsl:text>
</xsl:template>
<xsl:template match="alt/text" mode="alt">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">;</xsl:if>
</xsl:template>
<xsl:template match="alt/text"/>
</xsl:stylesheet>
或者更简单:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/root">
<xsl:text>[</xsl:text>
<xsl:for-each select="//text[not(parent::alt)]">
<xsl:text> 	{"text":"</xsl:text>
<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
<xsl:variable name="alt" select="following-sibling::*[1][self::alt]"/>
<xsl:if test="$alt">
<xsl:text>, "alternate":"</xsl:text>
<xsl:for-each select="$alt/text">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">;</xsl:if>
</xsl:for-each>
<xsl:text>"</xsl:text>
</xsl:if>
<xsl:text>}</xsl:text>
</xsl:for-each>
<xsl:text> ]</xsl:text>
</xsl:template>
</xsl:stylesheet>
所以,我有一份 XML 文档,大致如下所示:
<root>
<section>
<text>A</text>
<alt>
<text>1</text>
</alt>
<text>B</text>
<nest>
<text>C</text>
<alt>
<text>3</text>
</alt>
<text>D</text>
</nest>
<text>E</text>
<alt>
<text>4</text>
<text>5</text>
</alt>
</section>
</root>
我 运行 遇到的具体问题是 alt
标签。 alt
标签中的 text
标签是前一个兄弟的属性。
为了清楚起见,我想要的输出是这样的:
[
{"text": "A", "alternate": "1"},
{"text": "B"},
{"text": "C", "alternate": "3"},
{"text": "D"},
{"text": "E", "alternate": "4;5"}
]
也就是说,虽然nest
标签存在,但它的作用基本为空。我已经使用下面的 XSLT 脚本完成了大部分转换:
<xsl:template match="root">
<xsl:text>[</xsl:text>
<xsl:apply-templates select=".//section/item|.//section/nest/item"/>
<xsl:text>]</xsl:text>
</xsl:template>
<xsl:template match="section/item|section/nest/item">
<xsl:text>{</xsl:text>
<xsl:text>"text":"</xsl:text>
<xsl:value-of select="current()"/>
<xsl:text>"</xsl:text>
<xsl:if test="following-sibling::alt">
<xsl:text>, "alternate":"</xsl:text>
<xsl:apply-templates select="alt"/>
<xsl:text>"</xsl:text>
</xsl:if>
<xsl:text>}</xsl:text>
<xsl:if test="position() != last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="alt">
<xsl:for-each select="text">
<xsl:value-of select="current()"/>
<xsl:if test="position() != last()">
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
它运行,但实际上不识别 alt
元素。我假设这个测试有一些问题:<xsl:if test="following-sibling::alt">
不太正确,但我想不通以挽救我的生命。
我已经尝试过其他一些分组,但这是我能使用的最接近的版本。我主要是想弄清楚如何让这个兄弟测试和遍历工作正常进行,但是我在 XSLT 方面的专业知识水平很低,所以我可能只是从错误的角度来处理事情。
首选 XSLT 1.0。
您的 XSLT 与示例 XML 输入不匹配。给定示例输入,可以使用以下方法实现所需的输出:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/root">
<xsl:text>[</xsl:text>
<xsl:apply-templates/>
<xsl:text> ]</xsl:text>
</xsl:template>
<xsl:template match="text">
<xsl:text> 	{"text":"</xsl:text>
<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
<xsl:apply-templates select="following-sibling::*[1][self::alt]" mode="alt"/>
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:template match="alt" mode="alt">
<xsl:text>, "alternate":"</xsl:text>
<xsl:apply-templates mode="alt"/>
<xsl:text>"</xsl:text>
</xsl:template>
<xsl:template match="alt/text" mode="alt">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">;</xsl:if>
</xsl:template>
<xsl:template match="alt/text"/>
</xsl:stylesheet>
或者更简单:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/root">
<xsl:text>[</xsl:text>
<xsl:for-each select="//text[not(parent::alt)]">
<xsl:text> 	{"text":"</xsl:text>
<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
<xsl:variable name="alt" select="following-sibling::*[1][self::alt]"/>
<xsl:if test="$alt">
<xsl:text>, "alternate":"</xsl:text>
<xsl:for-each select="$alt/text">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">;</xsl:if>
</xsl:for-each>
<xsl:text>"</xsl:text>
</xsl:if>
<xsl:text>}</xsl:text>
</xsl:for-each>
<xsl:text> ]</xsl:text>
</xsl:template>
</xsl:stylesheet>