我的xml近似于:
<?xml version="1.0" encoding="UTF-8"?>
<book>
<num>Book 1.</num>
<head> Title</head>
<chapter>
<num>1.</num>
<head> The Begining</head>
<p>content</p>
</chapter>
<num>12. </num><p>we want that number untouched</p>
<chapter>
<num>2.</num>
<head> The Middle</head>
<p>content</p>
</chapter>
<head>Heads Occur</head><p>we want that head untouched</p>
</book>
<num>
紧跟<head>
之后我希望将两者合并在一起。我使用这个xsl,取得了一些成功,但并非在所有用例中都使用。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="num[following-sibling::head]">
<mergedhead>
<xsl:apply-templates select="node()|@*"/>
<xsl:value-of select="following-sibling::head"/>
</mergedhead>
</xsl:template>
<!-- keep the old head from showing up in the new output-->
<xsl:template match="head[preceding-sibling::num]"/>
</xsl:stylesheet>
following::sibling
和preceding::sibling
有效,但并非在所有用例中都有效。有时他们会将<num>
和<head>
拉入彼此不相邻的位置。输出我有缺陷的XSL:
<?xml version="1.0" encoding="UTF-8"?>
<book>
<mergedhead>Book 1. Title</mergedhead>
<chapter>
<mergedhead>1. The Begining</mergedhead>
<p>content</p>
</chapter>
<mergedhead>12. Heads Occur</mergedhead><p>we want that number untouched</p>
<chapter>
<mergedhead>2. The Middle</mergedhead>
<p>content</p>
</chapter>
<p>we want that head untouched</p>
</book>
你可以看到它合并了#12,我希望不受影响,并且'head occurrence',我也想要不受影响。我知道这是因为他们是兄弟姐妹,即使中间还有其他节点。我想我想要的答案是position()
。但我没有成功。
作为参考,所需的输出如下:
<?xml version="1.0" encoding="UTF-8"?>
<book>
<mergedhead>Book 1. Title</mergedhead>
<chapter>
<mergedhead>1. The Begining</mergedhead>
<p>content</p>
</chapter>
<num>12. </num><p>we want that number untouched</p>
<chapter>
<mergedhead>2. The Middle</mergedhead>
<p>content</p>
</chapter>
<head>Heads Occur</head><p>we want that head untouched</p>
</book>
答案 0 :(得分:2)
如果满足您的要求,请尝试使用xslt。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- Take all following sibling elements (i.e. following-sibling:*) regardless their names, from them take first one (i.e. [1]) and test it if it is head (i.e. [self::head]-->
<xsl:template match="num[following-sibling::*[1][self::head]]">
<mergedhead>
<xsl:apply-templates select="node()|@*"/>
<!-- Take the first following sibling -->
<xsl:value-of select="following-sibling::head[1]"/>
</mergedhead>
</xsl:template>
<!-- similar to num template -->
<xsl:template match="head[preceding-sibling::*[1][self::num]]"/>
</xsl:stylesheet>