I have an XML document with a structure similar to the following:
<article>
<header>
<metadata>
bunch of metadata nodes here
<abstract>
<p>this is one of the abstract's paragraphs</p>
</abstract>
</metadata>
</header>
<body>
<sec>
<title>This is title 1</title>
<p>Paragraph 1</p>
<p>paragraph 2</p>
<title>This is title 2</title>
<sec>
<title>This is title 3</title>
<p>paragraph 1 under title 3</p>
<p>paragraph 2 under title 3</p>
</body>
</article>
The real XML can certainly get a lot more complex that the above, but it should suffice to illustrate.
I need to apply a specific template only to the first <p>
element occurring inside the <body>
element. I can easily write an xpath expresion that selects for the the node I am interested in:
(//body//p)[1]
Unfortunately this xpath expression can not be used as the match expression in an XSLT
<xsl:template match="(//body//p)[1]">
<p_first>
<xsl:call-template name="copyElementAttributes" />
<xsl:apply-templates select="@*|node()" />
</p_first>
</xsl:template>
The template above will throw an error when trying to run it through the XSL engine. Is there a match expression that I can use to select the element?
You'd have to use something like
<xsl:template match="body//p[count(preceding::p) = count(ancestor::body/preceding::p)]">
ie to find a p
inside the body for which the number of other p
elements ahead of it is the same as the number ahead of the opening <body>
tag.
Alternatively
<xsl:template match="body//p[not(preceding::p[ancestor::body])]">
would look for a p
that does not have any predecessor p
elements that are themselves descendants of the body
. The ancestor::body
constraint is necessary because every body//p
is preceded by the p
that is inside the abstract
. It would get more complicated still if there could be more than one body
element, since we're only checking for p
s that are inside a body
element, not necessarily the same body
.
尝试match="body//p[not(preceding::p)]"
。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.