问题描述
我正在处理一个样式表,该样式表从输入文件中以几乎没有格式输出分层格式。每个部分的层次结构极其扁平,因此我一直在使用一种建议给我的分组方法-它按第一个节点名称对每个集合进行分组,从而使平坦部分具有很好的层次结构。此方法效果很好-我只需要修改它即可解决我想跳过的元素。
I'm working on a stylesheet that outputs in a hierarchical format from an input file with almost none. Each section has an extremely flat hierarchy, so I've been using a grouping method that was suggested to me - it groups each set by the first node name, and thus makes a nice heirarchy out of flat sections. This method works great - I just need to modify it to account for elements I want to skip over.
示例输入文件(注意:每个节中有多个Header元素) :
Sample input file (note: there are multiple Header elements per Section):
<Root>
<VolumeName>Volume 1 </VolumeName>
<Section>
<SectionName> Section1 </SectionName>
<Title> Title1 </Title>
<Header> NameOfDocument1 </Header>
<Header> Header1 </Header>
<Sub1> Sub1 first </Sub1>
<Sub1> Sub1 second </Sub1>
<Sub2> Sub2 first, Sub1 second </Sub2>
<Sub1> Sub1 third </Sub1>
<Sub2> Sub2 first, Sub1 third </Sub2>
</Section>
<Section>
<SectionName> Section2 </SectionName>
<Title> Title2 </Title>
<Header> Header2 </Header>
<Sub1> Sub1 first </Sub1>
<Sub1> Sub1 second </Sub1>
<Sub2> Sub2 first, Sub1 second </Sub2>
<Sub1> Sub1 third </Sub1>
<Sub2> Sub2 first, Sub1 third </Sub2>
</Section>
</Root>
示例输入代码的输出应类似于:
The output of the sample input code should look like:
<Volume1>
<Section1 Number="Section1" Name="NameOfDocument1" Title="Title1">
<Header1>
<Step>
Sub1 first
</Step>
<Step>
Sub1 second
<Step>
Sub2 first, Sub1 second
</Step>
</Step>
<Step>
Sub1 third
<Step>
Sub2 first, Sub1 third
</Step>
</Step>
</Header1>
</Section1>
<Section2 Number="Section2" Name="concat('NameOfDocument','2')" Title="Title2">
<Step>
Sub1 first
</Step>
<Step>
Sub1 second
<Step>
Sub2 first, Sub1 second
</Step>
</Step>
<Step>
Sub1 third
<Step>
Sub2 first, Sub1 third
</Step>
</Step>
</Section2>
</Volume1>
感谢Dimitrie Novatchev,我现在有一些代码可以处理Section元素内的扁平部分。我有一个与Section元素匹配的模板,然后声明了一个元素,并从SectionName,Title和Header中获取信息,以填写该元素的名称及其属性。我想跳过SectionName,Title,有时甚至是Header,但不确定如何修改Dimitrie的代码。任何建议将不胜感激!谢谢!
Thanks to Dimitrie Novatchev, I now have some code that will handle the flat parts inside the Section elements. I have a template match for the Section element, then I declare an element and grab information from SectionName, Title, and sometimes Header to fill in what the element will be called and its attributes. I want to skip SectionName, Title, and sometimes Header and I'm not sure how to modify Dimitrie's code to do so. Any suggestions would be greatly appreciated! Thank you!
Dimitrie的分组代码:
Dimitrie's grouping code:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<Root>
<xsl:apply-templates select="*[1]">
<xsl:with-param name="pScope" select="*"/>
<xsl:with-param name="pElemName" select="name(*[1])"/>
</xsl:apply-templates>
</Root>
</xsl:template>
<xsl:template match="*">
<xsl:param name="pScope"/>
<xsl:param name="pElemName" select="'Step'"/>
<xsl:for-each-group select="$pScope"
group-starting-with="*[name()= name($pScope[1])]">
<xsl:element name="{$pElemName}">
<xsl:value-of select="."/>
<xsl:apply-templates select="current-group()[2]">
<xsl:with-param name="pScope"
select="current-group()[position() > 1]"/>
</xsl:apply-templates>
</xsl:element>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
推荐答案
以下是我的答案的改编或产生现在想要的结果的最初问题:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<Root>
<xsl:element name="{translate(VolumeName,' ','')}">
<xsl:apply-templates/>
</xsl:element>
</Root>
</xsl:template>
<xsl:template match="*">
<xsl:param name="pScope"/>
<xsl:param name="pElemName" select="'Step'"/>
<xsl:for-each-group select="$pScope"
group-starting-with=
"*[name()= name($pScope[1])]">
<xsl:element name="{$pElemName}">
<xsl:value-of select="."/>
<xsl:apply-templates select="current-group()[2]">
<xsl:with-param name="pScope"
select="current-group()[position() > 1]"/>
</xsl:apply-templates>
</xsl:element>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="VolumeName"/>
<xsl:template match="Section">
<xsl:element name=
"{normalize-space(SectionName)}">
<xsl:attribute name="Number"
select="normalize-space(SectionName)"/>
<xsl:attribute name="Name" select=
"concat('NameOfDocument',
count(preceding-sibling::Section)+1)"/>
<xsl:attribute name="Title"
select="normalize-space(Title)"/>"
<xsl:variable name="vOutput">
<xsl:apply-templates select="*[1]">
<xsl:with-param name="pScope"
select="Header[last()]/following-sibling::*"/>
<xsl:with-param name="pElemName" select=
"(normalize-space(Header[2]), 'Step')[last()]"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:choose>
<xsl:when test="Header[2]">
<xsl:element name="{normalize-space(Header[2])}">
<xsl:sequence select="$vOutput"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="$vOutput"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
当此转换应用于提供的XML文档时:
<Root>
<VolumeName>Volume 1 </VolumeName>
<Section>
<SectionName> Section1 </SectionName>
<Title> Title1 </Title>
<Header> NameOfDocument1 </Header>
<Header> Header1 </Header>
<Sub1> Sub1 first </Sub1>
<Sub1> Sub1 second </Sub1>
<Sub2> Sub2 first, Sub1 second </Sub2>
<Sub1> Sub1 third </Sub1>
<Sub2> Sub2 first, Sub1 third </Sub2>
</Section>
<Section>
<SectionName> Section2 </SectionName>
<Title> Title2 </Title>
<Header> Header2 </Header>
<Sub1> Sub1 first </Sub1>
<Sub1> Sub1 second </Sub1>
<Sub2> Sub2 first, Sub1 second </Sub2>
<Sub1> Sub1 third </Sub1>
<Sub2> Sub2 first, Sub1 third </Sub2>
</Section>
</Root>
产生了所需的结果:
<Root>
<Volume1>
<Section1 Number="Section1" Name="NameOfDocument1" Title="Title1">"
<Header1>
<Step> Sub1 first </Step>
<Step> Sub1 second
<Step> Sub2 first, Sub1 second </Step></Step>
<Step> Sub1 third
<Step> Sub2 first, Sub1 third </Step></Step>
</Header1>
</Section1>
<Section2 Number="Section2" Name="NameOfDocument2" Title="Title2">"
<Step> Sub1 first </Step>
<Step> Sub1 second
<Step> Sub2 first, Sub1 second </Step></Step>
<Step> Sub1 third
<Step> Sub2 first, Sub1 third </Step></Step>
</Section2>
</Volume1>
</Root>
这篇关于XSLT 2.0-使用分组嵌套元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!