XSLT - 分析以下兄弟姐妹
XSLT - analyzing following-siblings
我有一个 xml 如下,
<doc>
<section>
<p id="main">main 1</p>
<p id="main">main 2</p>
<p id="para1">para1 1</p>
<p id="main">
<p>para1 sub1</p>
<p>para1 sub2</p>
</p>
<p id="main">para1 main2</p>
<p id="main">para1 main3</p>
<p id="chapter1">
<p>para2 sub1</p>
<p>para2 sub2</p>
</p>
<p id="main">para2 main1</p>
<p id="main">para2 main2</p>
<p id="main">para2 main3</p>
<p id="para1">para1 1</p>
<p id="main">
<p>para 1 sub3</p>
<p> para1 sub4</p>
</p>
<p id="main">para1 main2</p>
</section>
</doc>
如您所见,XML 只有一个 <section>
和 <p>
节点。 <p>
节点具有不同的属性 'main'
、'para1'
和 'para2'
我需要的是通过分析 <p>
节点分离到 <p>
节点到 <section>
它开始 <p>
的新属性的地方。并将 'para1'
和 'para2'
属性更改为 'main-para1'
和 'main-para2'
所以我的预期输出是,
<doc>
<section>
<p id="main">main 1</p>
<p id="main">main 2</p>
</section>
<section>
<p id="main-para1">para1 1</p>
<p id="main">
<p>para1 sub1</p>
<p>para1 sub2</p>
</p>
<p id="main">para1 main2</p>
<p id="main">para1 main3</p>
</section>
<section>
<p id="main-chapter1">
<p>para2 sub1</p>
<p>para2 sub2</p>
</p>
<p id="main">para2 main1</p>
<p id="main">para2 main2</p>
<p id="main">para2 main3</p>
</section>
<section>
<p id="main-para1">para1 1</p>
<p id="main">
<p>para 1 sub3</p>
<p>para 1 sub4</p>
</p>
<p id="main">para1 main2</p>
</section>
</doc>
我为完成任务而编写的 xsl 如下
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p[preceding-sibling::p[@id='para1']][following-sibling::p[@id='para2']]"/>
<xsl:template match="p[preceding-sibling::p[@id='para2']][following-sibling::p[@id='para1']]"/>
<xsl:template match="p[@id='para1']">
<section>
<p id="main-para1">
<xsl:apply-templates/>
</p>
</section>
</xsl:template>
<xsl:template match="p[@id='para2']">
<section>
<p id="main-para2">
<xsl:apply-templates/>
</p>
</section>
</xsl:template>
但是我有几个问题无法在上面的 XSL 代码中解决,
1) 新 <section>
作为 chid 添加到现有 <section>
节点。但我需要它作为现有 <section>
的兄弟姐妹(如预期输出所示。)
2) <p id="main-para1">
和 <p id="main-para1">
的后续兄弟未复制到 <section>
任何人都可以建议我如何修改我的代码以获得预期的输出吗?
提前致谢!
我相信这个returns预期的结果:
XSLT 2.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"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<xsl:for-each-group select="p" group-starting-with="p[starts-with(@id, 'para')]">
<section>
<xsl:apply-templates select="current-group()"/>
</section>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="p/@id[starts-with(., 'para')]">
<xsl:attribute name="id" select="concat('main-', .)"/>
</xsl:template>
</xsl:stylesheet>
我有一个 xml 如下,
<doc>
<section>
<p id="main">main 1</p>
<p id="main">main 2</p>
<p id="para1">para1 1</p>
<p id="main">
<p>para1 sub1</p>
<p>para1 sub2</p>
</p>
<p id="main">para1 main2</p>
<p id="main">para1 main3</p>
<p id="chapter1">
<p>para2 sub1</p>
<p>para2 sub2</p>
</p>
<p id="main">para2 main1</p>
<p id="main">para2 main2</p>
<p id="main">para2 main3</p>
<p id="para1">para1 1</p>
<p id="main">
<p>para 1 sub3</p>
<p> para1 sub4</p>
</p>
<p id="main">para1 main2</p>
</section>
</doc>
如您所见,XML 只有一个 <section>
和 <p>
节点。 <p>
节点具有不同的属性 'main'
、'para1'
和 'para2'
我需要的是通过分析 <p>
节点分离到 <p>
节点到 <section>
它开始 <p>
的新属性的地方。并将 'para1'
和 'para2'
属性更改为 'main-para1'
和 'main-para2'
所以我的预期输出是,
<doc>
<section>
<p id="main">main 1</p>
<p id="main">main 2</p>
</section>
<section>
<p id="main-para1">para1 1</p>
<p id="main">
<p>para1 sub1</p>
<p>para1 sub2</p>
</p>
<p id="main">para1 main2</p>
<p id="main">para1 main3</p>
</section>
<section>
<p id="main-chapter1">
<p>para2 sub1</p>
<p>para2 sub2</p>
</p>
<p id="main">para2 main1</p>
<p id="main">para2 main2</p>
<p id="main">para2 main3</p>
</section>
<section>
<p id="main-para1">para1 1</p>
<p id="main">
<p>para 1 sub3</p>
<p>para 1 sub4</p>
</p>
<p id="main">para1 main2</p>
</section>
</doc>
我为完成任务而编写的 xsl 如下
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p[preceding-sibling::p[@id='para1']][following-sibling::p[@id='para2']]"/>
<xsl:template match="p[preceding-sibling::p[@id='para2']][following-sibling::p[@id='para1']]"/>
<xsl:template match="p[@id='para1']">
<section>
<p id="main-para1">
<xsl:apply-templates/>
</p>
</section>
</xsl:template>
<xsl:template match="p[@id='para2']">
<section>
<p id="main-para2">
<xsl:apply-templates/>
</p>
</section>
</xsl:template>
但是我有几个问题无法在上面的 XSL 代码中解决,
1) 新 <section>
作为 chid 添加到现有 <section>
节点。但我需要它作为现有 <section>
的兄弟姐妹(如预期输出所示。)
2) <p id="main-para1">
和 <p id="main-para1">
的后续兄弟未复制到 <section>
任何人都可以建议我如何修改我的代码以获得预期的输出吗?
提前致谢!
我相信这个returns预期的结果:
XSLT 2.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"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<xsl:for-each-group select="p" group-starting-with="p[starts-with(@id, 'para')]">
<section>
<xsl:apply-templates select="current-group()"/>
</section>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="p/@id[starts-with(., 'para')]">
<xsl:attribute name="id" select="concat('main-', .)"/>
</xsl:template>
</xsl:stylesheet>