2

XSLT2.0を使用して1つのxmlを別のxmlに変換したいのですが、その間、ここで説明したシナリオに関するいくつかのXML要素のインデックスを見つけたいと思います...

これは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ドキュメントにこの要素が含まれている場合は、「ブックマーク」という名前の要素を1つ作成し、属性「インデックス」を設定します。
  2. 私のxmlドキュメントにこの要素が含まれていない場合は何もしません...

インデックスカウントはゼロから始まり、インデックスの計算から要素を省略する必要があり<w:sdt>ます。xmlドキュメントのコメントを参照してください。

私の必要な出力は:

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

2 に答える 2

3

これを試して ...

<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>
于 2012-07-06T07:13:00.567 に答える
3

この短くて単純な変換では、次のものを使用します<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>
于 2012-07-06T13:40:31.043 に答える