如何获得相对于特定的XML元素的索引来此方案在XSLT 2.0吗?(How to get the P

2019-06-26 02:41发布

我想通过使用XSLT2.0.While这样一个XML转换为另一种XML,我想找出一些XML元素的索引相对于我的scenaio我在这里所说...

这是XML文档:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:body>
        <w:sdt>
            <w:sdtContent>
                <w:p>
                    <w:pPr>
                        <w:pStyle w:val="TOC"></w:pStyle>
                    </w:pPr>
                </w:p>
            </w:sdtContent>
        </w:sdt>

        <w:p>   <!-- index value 0 -->
        </w:p>

        <w:p>   <!-- index value 1 -->
        </w:p>

        <w:Bookmark></w:Bookmark> <!-- index value 2 -->
        <w:Bookmark></w:Bookmark> <!-- index value 3 -->    

        <w:pict></w:pict> <!-- index value 4 -->

        <w:p>     <!-- index value 5 -->
        </w:p>

        <w:Bookmark></w:Bookmark> <!-- index value 6 -->
        <w:Bookmark></w:Bookmark> <!-- index value 7 -->        
        <w:p>  <!-- index value 8 -->
        </w:p>      

    </w:body>
</w:document>

所以,我想找到<w:Bookmark>元素的索引。

  1. 如果我的XML文档中包含此元素的话,我想创建一个名为“书签”一个元素,设置属性“索引”。
  2. 如果我的XML文档不包含此元素不会做任何事情......

该指数计数从零开始,我需要省略<w:sdt>从计算index.Please看到我的XML文档注释元素。

我需要的输出是:

  <Document>
    <Bookmark indexes="2,3,6,7">
    </Bookmark>
    </Document>

Answer 1:

试试这个 ...

<xsl:stylesheet 
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  xmlns:user="http://http://stackoverflow.com/questions/11356668"
  exclude-result-prefixes="xs fn w user">

<xsl:output indent="yes"/>

<xsl:function name="user:bookmark-index" as="xs:string">
  <xsl:param name="bookmark-node" as="element()"/>
  <xsl:for-each select="$bookmark-node">
    <xsl:value-of select="count( preceding-sibling::*) -
                          count( preceding-sibling::w:sdt)" />
  </xsl:for-each>
</xsl:function>

<xsl:template match="/">
 <Document>
  <Bookmark indexes="{
    fn:string-join( for $i in w:document/w:body/w:Bookmark return user:bookmark-index( $i), ',')
    }" />
 </Document>
</xsl:template>

</xsl:stylesheet>

......或者这相当于没有功能...

<xsl:stylesheet 
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  exclude-result-prefixes="xs fn w">

<xsl:output indent="yes"/>

<xsl:template match="/">
 <Document>
  <Bookmark indexes="{
    fn:string-join( for $i in w:document/w:body/w:Bookmark return
            xs:string( count($i/preceding-sibling::*) -
                       count($i/preceding-sibling::w:sdt)),
                  ',')
    }" />
 </Document>
</xsl:template>

</xsl:stylesheet>


Answer 2:

这种短且简单的变换使用<xsl:number>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
 exclude-result-prefixes="w xs">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*[//w:Bookmark]">
     <Document>
       <xsl:variable name="vIndexes" as="xs:string+">
        <xsl:apply-templates/>
       </xsl:variable>
       <Bookmark indexes="{string-join($vIndexes, ',')}"/>
     </Document>
 </xsl:template>

 <xsl:template match="w:Bookmark">
  <xsl:variable name="vPos" as="xs:integer">
    <xsl:number count="/*/w:body/*[not(self::w:sdt)]" level="any"/>
  </xsl:variable>

  <xsl:sequence select="string($vPos -1)"/>
 </xsl:template>
</xsl:stylesheet>

当施加在提供的XML文档:

<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
        <w:body>
            <w:sdt>
                <w:sdtContent>
                    <w:p>
                        <w:pPr>
                            <w:pStyle w:val="TOC"></w:pStyle>
                        </w:pPr>
                    </w:p>
                </w:sdtContent>
            </w:sdt>

            <w:p>   <!-- index value 0 -->
            </w:p>

            <w:p>   <!-- index value 1 -->
            </w:p>

            <w:Bookmark></w:Bookmark> <!-- index value 2 -->
            <w:Bookmark></w:Bookmark> <!-- index value 3 -->

            <w:pict></w:pict> <!-- index value 4 -->

            <w:p>     <!-- index value 5 -->
            </w:p>

            <w:Bookmark></w:Bookmark> <!-- index value 6 -->
            <w:Bookmark></w:Bookmark> <!-- index value 7 -->
            <w:p>  <!-- index value 8 -->
            </w:p>

        </w:body>
</w:document>

在想,正确的结果产生:

<Document>
   <Bookmark indexes="2,3,6,7"/>
</Document>


文章来源: How to get the Particular XML elements indexes with respect to this scenario in xslt 2.0?