我有写xsl的问题,将我的xml转换为raport版本。 它看起来像是:
<library>
<authors>
<author id="1001">John</author>
<author id="1002">Tom</author>
</authors>
<articles>
<article>
<authorId>1001</authorId>
<title>Article1</title>
</article>
<article>
<authorId>1002</authorId>
<title>Article2</title>
</article>
<article>
<authorId>1001</authorId>
<title>Article3</title>
</article>
</articles>
</library>
我想将其转换为:
<raport>
<authorArticles>
<author>John</author>
<articles>
<article>Article1</article>
<article>Article3</article>
</articles>
</authorArticles>
<authorArticles>
<author>Tom</author>
<articles>
<article>Article2</article>
</articles>
</authorArticles>
</raport>
我有想法为每个人使用,为作者的ids使用并且需要文章,但我不知道该怎么做。有谁知道如何进行这种转变?
答案 0 :(得分:1)
这个XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node() | @*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="library">
<raport>
<xsl:apply-templates select="authors/author"/>
</raport>
</xsl:template>
<xsl:template match="author">
<authorArticles>
<xsl:call-template name="identity"/>
<articles>
<xsl:apply-templates select="../../articles/article[authorId = current()/@id]"/>
</articles>
</authorArticles>
</xsl:template>
<xsl:template match="article">
<xsl:call-template name="identity"/> <!-- In case of more characteristics -->
</xsl:template>
<xsl:template match="title">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="author/@id | authorId"/>
</xsl:stylesheet>
使用此XML输入:
<library>
<authors>
<author id="1001">John</author>
<author id="1002">Tom</author>
</authors>
<articles>
<article>
<authorId>1001</authorId>
<title>Article1</title>
</article>
<article>
<authorId>1002</authorId>
<title>Article2</title>
</article>
<article>
<authorId>1001</authorId>
<title>Article3</title>
</article>
</articles>
</library>
提供所需的结果:
<raport>
<authorArticles>
<author>John</author>
<articles>
<article>Article1</article>
<article>Article3</article>
</articles>
</authorArticles>
<authorArticles>
<author>Tom</author>
<articles>
<article>Article2</article>
</articles>
</authorArticles>
</raport>
进一步的优化可能是使用键,但结构看起来不成熟。
答案 1 :(得分:1)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kArticleById" match="article"
use="authorId"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<raport>
<xsl:apply-templates select="authors/author"/>
</raport>
</xsl:template>
<xsl:template match="author">
<authorArticles>
<xsl:call-template name="identity"/>
<articles>
<xsl:apply-templates select="key('kArticleById',@id)"/>
</articles>
</authorArticles>
</xsl:template>
<xsl:template match="title">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="author/@id|articles|authorId"/>
</xsl:stylesheet>
应用于提供的XML文档:
<library>
<authors>
<author id="1001">John</author>
<author id="1002">Tom</author>
</authors>
<articles>
<article>
<authorId>1001</authorId>
<title>Article1</title>
</article>
<article>
<authorId>1002</authorId>
<title>Article2</title>
</article>
<article>
<authorId>1001</authorId>
<title>Article3</title>
</article>
</articles>
</library>
生成想要的正确结果:
<raport>
<authorArticles>
<author>John</author>
<articles>
<article>Article1</article>
<article>Article3</article>
</articles>
</authorArticles>
<authorArticles>
<author>Tom</author>
<articles>
<article>Article2</article>
</articles>
</authorArticles>
</raport>
备注强>:
使用/覆盖身份规则。
使用键选择具有相同authorId的所有文章。如果许多作者有很多文章,这种效率要高得多。