无法使用XSLT 2.0获取所需的XML元素?

时间:2012-07-24 09:21:31

标签: xml xpath xslt-1.0 xslt-2.0 xpath-2.0

这是我的XML文档。我想将此XML文档转换为另一个XML文档(请参阅所需的输出XML部分)。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
                xmlns:v="urn:schemas-microsoft-com:vml">
    <w:body>
        <w:p>
            <w:pPr>
            </w:pPr>
            <w:r>
                <w:t>Text1-</w:t>
            </w:r>  
        </w:p>

        <w:p>
            <w:pPr>
                <w:pStyle w:val="Heading2" /> 
            </w:pPr>
            <w:r>
                <w:t>Text2-</w:t>
            </w:r>  
        </w:p>

        <w:p>
            <w:pPr>
            </w:pPr>
            <w:r>
                <w:t>Text3-</w:t>
            </w:r>  
        </w:p>

        <w:p>
            <w:pPr>
            </w:pPr>
            <w:r>
                <w:t>Text4-</w:t>
            </w:r>  
        </w:p>

         <w:p>
            <w:pPr>
                <w:pStyle w:val="Heading3" /> 
            </w:pPr>
            <w:r>
                <w:t>Text2.1-</w:t>
            </w:r>  
        </w:p>

        <w:p>
            <w:pPr>
                <w:pStyle w:val="Heading2" /> 
            </w:pPr>
            <w:r>
                <w:t>Text5-</w:t>
            </w:r>  
        </w:p>

        <w:p>
            <w:pPr>
            </w:pPr>
            <w:r>
                <w:t>Text6-</w:t>
            </w:r>  
        </w:p>

        <w:p>
            <w:pPr>
                <w:pStyle w:val="Heading3" /> 
            </w:pPr>
            <w:r>
                <w:t>Text7-</w:t>
            </w:r>  
        </w:p>

        <w:p>
            <w:pPr>
            </w:pPr>
            <w:r>
                <w:t>Text8-</w:t>
            </w:r>  
        </w:p>  

        <w:p>
            <w:pPr>
                <w:pStyle w:val="Heading1" /> 
            </w:pPr>
            <w:r>
                <w:t>Text9-</w:t>
            </w:r>  
        </w:p>

        <w:p>
            <w:pPr>
            </w:pPr>
            <w:r>
                <w:t>Text10-</w:t>
            </w:r>  
        </w:p>

<w:p>
            <w:pPr>
                <w:pStyle w:val="Heading2" /> 
            </w:pPr>
            <w:r>
                <w:t>Text11-</w:t>
            </w:r>  
        </w:p>

        <w:p>
            <w:pPr>
            </w:pPr>
            <w:r>
                <w:t>Text12-</w:t>
            </w:r>  
        </w:p>

        <w:p>
            <w:r>
                <w:pict>
                    <v:shape>
                        <v:textbox>
                            <w:txbxcontent>
                                <w:p>
                                    <w:pPr>
                                        <w:pStyle w:val="Heading1" /> 
                                    </w:pPr>
                                    <w:r>
                                        <w:t>   
                                            Drawing Description_1
                                        </w:t>
                                    </w:r>
                                </w:p>          
                                <w:p>
                                    <w:pPr>
                                        <w:pStyle w:val="Heading1" /> 
                                    </w:pPr>
                                    <w:r>
                                        <w:t>   
                                            Drawing Description_2
                                        </w:t>
                                    </w:r>
                                </w:p>
                            </w:txbxcontent>
                        </v:textbox>
                    </v:shape>
                </w:pict>
            </w:r>
        </w:p>

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

所需的输出XML 是:

 <?xml version="1.0" encoding="utf-8"?><Document xmlns:v="urn:schemas-microsoft-com:vml" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
    <Paragraph>Text1-</Paragraph>
    <Heading2>
       <Title>Text2-</Title>
       <Paragraph>Text3-</Paragraph>
       <Paragraph>Text4-</Paragraph>
       <Heading3>
          <Title>Text2.1-</Title>
       </Heading3>
    </Heading2>
    <Heading2>
       <Title>Text5-</Title>
       <Paragraph>Text6-</Paragraph>
       <Heading3>
         <Title>Text7-</Title>
         <Paragraph>Text8-</Paragraph>
       </Heading3>
   </Heading2>
   <Heading1>
      <Title>Text9-</Title>
      <Paragraph>Text10-</Paragraph>
      <Heading2>
       <Title>Text11-</Title>
         <Paragraph>Text12-</Paragraph>
         <txtContentGroup>
              <Paragraph>Drawing Description_1</Paragraph>
              <Paragraph>Drawing Description_2</Paragraph>
         </txtContentGroup>
       </Heading2>
    </Heading1>
 </Document>

这是我的XSLT 2.0实现:

<xsl:stylesheet 
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xpath-default-namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
  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:mf="http://example.com/mf"
  xmlns:v="urn:schemas-microsoft-com:vml"
  xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"
  xmlns:user="http://http://stackoverflow.com/questions/11356668"
  exclude-result-prefixes="xs w fn mf user">

  <xsl:output indent="yes"/> 

  <xsl:function name="mf:group" as="element()*">
      <xsl:param name="paragraphs" as="element()*"/>
      <xsl:param name="level" as="xs:integer"/>

      <xsl:for-each-group select="$paragraphs" group-starting-with="p[pPr/pStyle/@w:val = concat('Heading', $level)]">   

        <xsl:choose>
            <xsl:when test="self::p[pPr/pStyle/@w:val = concat('Heading', $level)]">
                <xsl:element name="Heading{$level}">
                <Title>
                  <xsl:apply-templates select="./r/t"/>
                </Title>                

                <xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
          </xsl:element>
        </xsl:when>

        <xsl:when test="current-group()[self::p[pPr/pStyle/@w:val = concat('Heading', $level + 1)]]">
          <xsl:sequence select="mf:group(current-group(), $level + 1)">
          </xsl:sequence>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="current-group()">
           </xsl:apply-templates>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each-group>
  </xsl:function>

  <xsl:template match="document">

    <Document>
       <xsl:sequence select="mf:group(body/p, 1)"/>
    </Document>

  </xsl:template>

  <xsl:template match="p">

      <xsl:choose>
           <xsl:when test="(./r/t)">
               <xsl:choose>
                 <xsl:when test="descendant::w:p[w:r/w:t] | descendant::w:p[//w:r/w:t[ancestor::w:pict]][2] ">         
                       <txtContentGroup>            

                                <Paragraph>              
                                    <xsl:apply-templates select="./r/t"/>            
                              </Paragraph>

                              <xsl:apply-templates select="descendant::w:p">
                              </xsl:apply-templates>  

                       </txtContentGroup>          
                </xsl:when>  

                <xsl:otherwise>         
                    <Paragraph>
                       <xsl:apply-templates select="./r/t"/>
                    </Paragraph>
        </xsl:otherwise>
      </xsl:choose>

      </xsl:when>
         <xsl:otherwise>
           <xsl:choose>
             <xsl:when test="descendant::w:p[not(ancestor::w:tbl)]">
               <xsl:apply-templates select="descendant::w:p">
               </xsl:apply-templates>
             </xsl:when>     
            </xsl:choose>
         </xsl:otherwise>
       </xsl:choose>
    </xsl:template>

  <xsl:template match="/r/t">
    <xsl:value-of select="."/>
  </xsl:template> 
</xsl:stylesheet>

但它会产生以下输出:

    <?xml version="1.0" encoding="utf-8"?><Document xmlns:v="urn:schemas-microsoft-com:vml" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
    <Paragraph>Text1-</Paragraph>
    <Heading2>
       <Title>Text2-</Title>
       <Paragraph>Text3-</Paragraph>
       <Paragraph>Text4-</Paragraph>
       <Heading3>
         <Title>Text2.1-</Title>
      </Heading3>
    </Heading2>
    <Heading2>
       <Title>Text5-</Title>
       <Paragraph>Text6-</Paragraph>
       <Heading3>
         <Title>Text7-</Title>
         <Paragraph>Text8-</Paragraph>
       </Heading3>
    </Heading2>
    <Heading1>
       <Title>Text9-</Title>
       <Paragraph>Text10-</Paragraph>
       <Heading2>
          <Title>Text11-</Title>
          <Paragraph>Text12-</Paragraph>
          <Paragraph>Drawing Description_1</Paragraph>
          <Paragraph>Drawing Description_2</Paragraph>
       </Heading2>
   </Heading1>
   </Document>

我的条件是:

每当<w:p>元素中包含多个 descendant::w:p[w:r/w:t]descendant::w:p[w:r/w:t]的祖先为<w:pict>时,我就想创建<txtContentGroup>元素并将所有descendant::w:p[w:r/w:t]放入其中。

1 个答案:

答案 0 :(得分:1)

使用这种输入你应该使用模板规则,而不是深层嵌套的xsl:选择说明。你的英文声明

每当<w:p>个元素中包含多个descendant::w:p[w:r/w:t]并且它的祖先为<w:pict>时,我就想创建<txtContentGroup>个元素并放置所有descendant::w:p[w:r/w:t]元素{1}}在里面。

直接映射到模板规则:

<xsl:template match="w:pict//w:p[descendant::w:p[w:r/w:t][2]]">
  <textContentGroup>
    <xsl:apply-templates select="descendant::w:p[w:r/w:t]"/>
  </textContentGroup>
</xsl:template>