В любой подобной задаче можно использовать формулу Кейсиана для пересечения набора узлов .
Если у нас есть два набора узлов $ns1
и $ns2
, то все узлы, которые принадлежатоба набора узлов выбираются этим выражением XPath:
$ns1[count(.|$ns2) = count($ns2)]
В вашем случае вам нужно просто заменить $ns1
на :
//w:r[w:fldChar/@w:fldCharType='begin'][1]/following-sibling::*
..
и замените $ns2
на :
//w:r[w:fldChar/@w:fldCharType='end'][1]/preceding-sibling::*
Полученное выражение XPath может показаться слишком сложным, но вы получаете возможность очень легко решить любую такую проблемуи почти механически:
/*/w:r
[w:fldChar/@w:fldCharType='begin']/following-sibling::*
[count(. | /*/w:r[w:fldChar/@w:fldCharType='end']
/preceding-sibling::*
)
=
count(/*/w:r[w:fldChar/@w:fldCharType='end']
/preceding-sibling::*)
]
проверка на основе XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="some:namespace">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/w:r
[w:fldChar/@w:fldCharType='begin']/following-sibling::*
[count(. | /*/w:r[w:fldChar/@w:fldCharType='end']
/preceding-sibling::*
)
=
count(/*/w:r[w:fldChar/@w:fldCharType='end']
/preceding-sibling::*)
]
"/>
</xsl:template>
</xsl:stylesheet>
, когда это преобразование применяется к этому документу XML :
<t xmlns:w="some:namespace">
<w:r>
<w:fldChar w:fldCharType="before-begin"/>
</w:r>
<w:r>
<w:fldChar w:fldCharType="begin"/>
</w:r>
<w:r>
<w:instrText> DOCPROPERTY EvidenceBase \* MERGEFORMAT </w:instrText>
</w:r>
<w:r>
<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:r>
<w:t>EvidenceBase</w:t>
</w:r>
<w:r>
<w:fldChar w:fldCharType="end"/>
</w:r>
<w:r>
<w:fldChar w:fldCharType="after-end"/>
</w:r>
</t>
точно требуемые элементы выбираются и копируются на выход :
<w:r xmlns:w="some:namespace">
<w:instrText> DOCPROPERTY EvidenceBase \* MERGEFORMAT </w:instrText>
</w:r>
<w:r xmlns:w="some:namespace">
<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:r xmlns:w="some:namespace">
<w:t>EvidenceBase</w:t>
</w:r>