Xml XSLT:选择以下同级,直到到达指定的标记
我正在尝试编写XSLT,该XSLT将在所选的以下同级上运行for each,但在到达另一个标记(h1)时停止 以下是源XML:Xml XSLT:选择以下同级,直到到达指定的标记,xml,xslt,Xml,Xslt,我正在尝试编写XSLT,该XSLT将在所选的以下同级上运行for each,但在到达另一个标记(h1)时停止 以下是源XML: <?xml version="1.0"?> <html> <h1>Test</h1> <p>Test: p 1</p> <p>Test: p 2</p> <h1>Test 2</h1> <p>Test
<?xml version="1.0"?>
<html>
<h1>Test</h1>
<p>Test: p 1</p>
<p>Test: p 2</p>
<h1>Test 2</h1>
<p>Test2: p 1</p>
<p>Test2: p 2</p>
<p>Test2: p 3</p>
</html>
试验
测试:P1
测试:P2
测试2
测试2:p1
测试2:p2
测试2:p3
以下是XSLT:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<content>
<xsl:apply-templates/>
</content>
</xsl:template>
<xsl:template match="h1">
<section>
<sectionHeading>
<xsl:apply-templates/>
</sectionHeading>
<sectionContent>
<xsl:for-each select="following-sibling::p">
<paragraph>
<xsl:value-of select="."/>
</paragraph>
</xsl:for-each>
</sectionContent>
</section>
</xsl:template>
<xsl:template match="p"/>
</xsl:stylesheet>
以下是当前的结果:
<?xml version="1.0" encoding="UTF-8"?>
<content>
<section>
<sectionHeading>Test</sectionHeading>
<sectionContent>
<paragraph>Test: p 1</paragraph>
<paragraph>Test: p 2</paragraph>
<paragraph>Test: p 3</paragraph>
<paragraph>Test2: p 1</paragraph>
<paragraph>Test2: p 2</paragraph>
</sectionContent>
</section>
<section>
<sectionHeading>Test 2</sectionHeading>
<sectionContent>
<paragraph>Test2: p 1</paragraph>
<paragraph>Test2: p 2</paragraph>
</sectionContent>
</section>
</content>
试验
测试:P1
测试:P2
测试:p3
测试2:p1
测试2:p2
测试2
测试2:p1
测试2:p2
以下是预期结果:
<?xml version="1.0" encoding="UTF-8"?>
<content>
<section>
<sectionHeading>Test</sectionHeading>
<sectionContent>
<paragraph>Test: p 1</paragraph>
<paragraph>Test: p 2</paragraph>
<paragraph>Test: p 3</paragraph>
</sectionContent>
</section>
<section>
<sectionHeading>Test 2</sectionHeading>
<sectionContent>
<paragraph>Test2: p 1</paragraph>
<paragraph>Test2: p 2</paragraph>
</sectionContent>
</section>
</content>
试验
测试:P1
测试:P2
测试:p3
测试2
测试2:p1
测试2:p2
试试这个:(我们不要求所有的p,而是要求所有最近上一个h1为当前的p。)
被接受的答案有不良的副作用,而且有点错误。
在这篇文章中,我将进一步解释以下基本陈述的真实比较,以及为什么可以和将失败
在模板中回顾/分析情况
:
- 当前上下文节点是匹配的
中的任何h1
- 名为
的变量包含当前上下文节点的副本header
- 选择我的上下文节点的所有后续同级
|p
后续同级::p
- 过滤这些
,其中名为p
的前一个(最近的)兄弟姐妹“与变量h1
|$header
相同,…[前一个兄弟姐妹::h1[1]=$header]
请看一个例子。让我们假设输入xml如下[
包含两次相同的值Test
]:
<html>
<h1>Test</h1>
<p>Test: p 1</p>
<p>Test: p 2</p>
<h1>Test</h1>
<p>Test2: p 1</p>
<p>Test2: p 2</p>
<p>Test2: p 3</p>
</html>
试验
测试:P1
测试:P2
试验
测试2:p1
测试2:p2
测试2:p3
A!错了将创建以下结果:
<content>
<section>
<sectionHeading>Test</sectionHeading>
<sectionContent>
<paragraph>Test: p 1</paragraph>
<paragraph>Test: p 2</paragraph>
<paragraph>Test2: p 1</paragraph> <-- should be only in 2. section
<paragraph>Test2: p 2</paragraph> <-- should be only in 2. section
<paragraph>Test2: p 3</paragraph> <-- should be only in 2. section
</sectionContent>
</section>
<section>
<sectionHeading>Test</sectionHeading>
<sectionContent>
<paragraph>Test2: p 1</paragraph>
<paragraph>Test2: p 2</paragraph>
<paragraph>Test2: p 3</paragraph>
</sectionContent>
</section>
</content>
试验
测试:P1
测试:P2
测试2:P1刚刚测试了这个,它工作得非常好。非常感谢。@Tim,虽然我们可以找到xslt的解决方案,但我还是建议您将xml格式更改为TestTest:p1Test:p2Test2:p1Test2:p2Test2:p3,这样更有意义且可读性,在xslt中也很容易查询。为什么不编辑已接受的解决方案并添加注释呢?我对此投了反对票,因为您完全可以编辑正确的响应或留下注释。
<content>
<section>
<sectionHeading>Test</sectionHeading>
<sectionContent>
<paragraph>Test: p 1</paragraph>
<paragraph>Test: p 2</paragraph>
<paragraph>Test2: p 1</paragraph> <-- should be only in 2. section
<paragraph>Test2: p 2</paragraph> <-- should be only in 2. section
<paragraph>Test2: p 3</paragraph> <-- should be only in 2. section
</sectionContent>
</section>
<section>
<sectionHeading>Test</sectionHeading>
<sectionContent>
<paragraph>Test2: p 1</paragraph>
<paragraph>Test2: p 2</paragraph>
<paragraph>Test2: p 3</paragraph>
</sectionContent>
</section>
</content>
...
<xsl:template match="h1">
<xsl:variable name="header" select="generate-id(.)"/>
<section>
<sectionHeading>
<xsl:apply-templates/>
</sectionHeading>
<sectionContent>
<xsl:for-each select="following-sibling::p[generate-id(preceding-sibling::h1[1]) = $header]">
<paragraph>
<xsl:value-of select="."/>
</paragraph>
</xsl:for-each>
</sectionContent>
</section>
</xsl:template>
...