我是XSLT的相对新手,自90年代末以来一直没有接触过XSLT,但最近我开始了一个涉及XSLT的个人项目。
我有以下XML,我正在尝试从它构建一个HTML字符表:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="./Statblock.xslt"?>
<Character>
<Name value="Seiyatomo"/>
<Family value="Soshi"/>
<Clan value="Scorpion"/>
<School value="Soshi Illusionist School"/>
<Titles/>
<Ninjo value=""/>
<Giri value=""/>
<Abilities>
<Ability description="" name="The Kami's Whisper" />
</Abilities>
<Skills>
...
</Skills>
<Rings>
...
</Rings>
<Social glory="50" honor="35" status="35"/>
<Wealth bu="0" koku="6" zeni="0"/>
<Derived composure="8" endurance="4" focus="4" vigilance="3"/>
<RankStatus titlestatus="Title: , Title XP: 0" curricstatus="Rank: 1, XP in Rank: 0"/>
<Curriculum>
...
</Curriculum>
<Title/>
<Techniques>
<Technique name="Bō of Water" />
<Technique name="Cloak of Night" />
<Technique name="Token of Memory" />
<Technique name="Commune with the Spirits" />
<Technique name="All in Jest" />
<Technique name="Dangerous Allure" />
<Technique name="Shadowlands Taint (Water)" />
<Technique name="Curiosity" />
<Technique name="Dark Secret" />
<Technique name="Fallen Ancestor" />
</Techniques>
<PersonalTraits/>
<Equipment>
...
</Equipment>
<Heritage value="Glorious Sacrifice"/>
<Notes value="..."/>
<Advances/>
<TotalXP value="0"/>
<XPSpent value="0"/>
<Portrait base64image=""/>
</Character>我试图将能力和技术节点的组合列表分组为9,这样我就可以得到类似于以下内容的输出:
<page>
<ability>The Kami's Whisper</ability>
<technique>Bō of Water</technique>
<technique>Cloak of Night</technique>
<technique>Token of Memory</technique>
<technique>Commune with the Spirits</technique>
<technique>All in Jest</technique>
<technique>Dangerous Allure</technique>
<technique>Shadowlands Taint (Water)</technique>
<technique>Curiosity</technique>
</page>
<page>
<technique>Dark Secret</technique>
<technique>Fallen Ancestor</technique>
</page>XML中的节点数和节点数都是任意的,但我更希望所有节点都在输出中排在第一位,然后是节点。
加分,如果最后一个可以满是空条目,以填补整个页面集9,但这是次要的关注。
我试着寻找类似的问题,但要么我没有看到任何类似的问题,要么我没有足够的理解问题/答案来识别它们是重复的。
注意:如果有必要,可以让生成XML的应用程序的作者对XML进行一些更改,但我不能直接控制XML本身。
发布于 2019-08-14 04:44:09
至少第一部分看起来很简单:
XSLT1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Character">
<xsl:copy>
<xsl:copy-of select="Name" />
<xsl:call-template name="paginate">
<xsl:with-param name="nodes" select="Abilities/Ability | Techniques/Technique"/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template match="Ability">
<ability>
<xsl:value-of select="@name"/>
</ability>
</xsl:template>
<xsl:template match="Technique">
<technique>
<xsl:value-of select="@name"/>
</technique>
</xsl:template>
<xsl:template name="paginate">
<xsl:param name="nodes"/>
<xsl:param name="pagesize" select="9"/>
<page>
<xsl:apply-templates select="$nodes[position() <= $pagesize]"/>
</page>
<xsl:if test="count($nodes) > $pagesize">
<xsl:call-template name="paginate">
<xsl:with-param name="nodes" select="$nodes[position() > $pagesize]"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>在XSLT2.0中甚至更简单
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Character">
<xsl:copy>
<xsl:copy-of select="Name" />
<xsl:for-each-group select="Abilities/Ability | Techniques/Technique" group-by="(position()-1) idiv 9">
<page>
<xsl:apply-templates select="current-group()"/>
</page>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="Ability | Technique">
<xsl:element name="{lower-case(name())}">
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>对于第二部分,只需添加(在XSLT2.0中):
<xsl:for-each select="1 to 9 - count(current-group())">
<technique/>
</xsl:for-each>https://stackoverflow.com/questions/57487852
复制相似问题