如果与XSLT 2.0重复,请选择属性值,但不是

时间:2017-05-12 10:49:09

标签: xml xslt

我有一个OOXML文件,我想选择w:document / w:body / w:p / w:pPr / w:pStyle / @ w:val值,仅当w:p node有文本时。我的问题是我知道如何使用这个模板全部使用它们:

<xsl:template match="/">
    <DifferentStyles>
        <xsl:for-each select="w:document/w:body/w:p">
            <xsl:if test="w:pPr/w:pStyle/@w:val and w:r/w:t">
                <stylish>
                    <xsl:value-of select="w:pPr/w:pStyle/@w:val"/>
                </stylish>
            </xsl:if>
        </xsl:for-each>
    </DifferentStyles>
</xsl:template>

问题是我不知道如果价值相同怎么不考虑。我一直在调查generate-id和key taks,但我根本不理解它们。 在这里,我附上OOXML文件的一小部分:

<w:p w:rsidR="00046C79" w:rsidRDefault="00E24C8B">
        <w:pPr>
            <w:pStyle w:val="TitleHeading"/>
        </w:pPr>
        <w:bookmarkStart w:id="0" w:name="_GoBack"/>
        <w:bookmarkEnd w:id="0"/>
        <w:r>
            <w:t>Index</w:t>
        </w:r>
    </w:p>
    <w:p w:rsidR="00046C79" w:rsidRDefault="00E24C8B">
        <w:pPr>
            <w:pStyle w:val="TitleHeading"/>
        </w:pPr>
        <w:r>
            <w:t>-by-</w:t>
        </w:r>
    </w:p>
    <w:p w:rsidR="00046C79" w:rsidRDefault="00E24C8B">
        <w:pPr>
            <w:pStyle w:val="TitleHeading"/>
        </w:pPr>
        <w:r>
            <w:t>Cesar G.</w:t>
        </w:r>
    </w:p>
    <w:p w:rsidR="00046C79" w:rsidRDefault="00046C79">
        <w:pPr>
            <w:pStyle w:val="HeadingF"/>
            <w:rPr>
                <w:rStyle w:val="IntenseReference"/>
                <w:rFonts w:cs="Arial"/>
                <w:color w:val="auto"/>
            </w:rPr>
        </w:pPr>
    </w:p>
    <w:p w:rsidR="00046C79" w:rsidRDefault="00E24C8B">
        <w:pPr>
            <w:pStyle w:val="Heading"/>
        </w:pPr>
        <w:r>
            <w:t>referenced applications</w:t>
        </w:r>
    </w:p>
    <w:p w:rsidR="00046C79" w:rsidRDefault="00E24C8B">
        <w:pPr>
            <w:pStyle w:val="NumberedParagraph"/>
        </w:pPr>
        <w:r>
            <w:t xml:space="preserve">This application</w:t>
        </w:r>
    </w:p>

我想要下一个结果:

<DifferentStyles>
   <stylish>TitleHeading</stylish>
   <stylish>Heading</stylish>
   <stylish>NumberedParagraph</stylish>
</DifferentStyles>

谢谢,我希望有人可以帮助我!!

1 个答案:

答案 0 :(得分:0)

尝试使用以下简洁脚本来执行任务:

<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:w="http://dummy_w.com" xpath-default-namespace="http://dummy_w.com"
  exclude-result-prefixes="#all">
  <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="body">
    <DifferentStyles>
      <xsl:for-each select="distinct-values(p/pPr[../r/t]/pStyle/@w:val)">
        <stylish><xsl:value-of select="."/></stylish>
      </xsl:for-each>
    </DifferentStyles>
  </xsl:template>
</xsl:transform>

请注意:

  • xpath-default-namespace允许省略命名空间 规范(属性除外)。
  • 模板只能与body匹配。

select中的for-each子句如何运作:

  • 查找p/pPr个节点...
  • 其中r邻居t内有[../r/t]
  • 来自他们(我的意思是 pPr 节点)带走pStyle个孩子,
  • 从中获取val属性,
  • 最后,消除重复(distinct-values)。

或许您想要对这些样式进行排序?如果你这样做,请添加 <xsl:sort select="."/>之后的for_each