XSLT在匹配lxml python中获取父级

时间:2014-11-26 09:44:16

标签: python xml xslt xslt-1.0 lxml

我有这个XML:

<AAA>
    <BBB>
        <CCC>
            <DDD/>
        </CCC>
        <CCC>
            <EEE/>
        </CCC>
    </BBB>
    <BBB>
        <CCC>
            <EEE/>
        </CCC>
        <CCC>
            <DDD/>
        </CCC>
    </BBB>
    <BBB>
        <CCC>
            <EEE/>
        </CCC>
        <CCC>
            <EEE/>
        </CCC>
    </BBB>
    <BBB>
        <CCC>
            <DDD/>
        </CCC>
        <CCC>
            <EEE/>
        </CCC>
    </BBB>
</AAA>

我希望使用XSLT文件获得此结果:

<AAA>
   <XXX case="1" />
   <XXX case="2" />
   <XXX case="3" />
   <XXX case="1" />
</AAA>

Case 1: CCC[1] has DDD & CCC[2] has EEE
Case 2: CCC[1] has EEE & CCC[2] has DDD
Case 3: CCC[1] has EEE & CCC[2] has EEE

CCC总是只有一个项目

我在Python中使用lxml库。 我已经有一个匹配case =&#34; 1&#34;的XPath在Notepad ++中:

//BBB/CCC[1]/DDD/../../CCC[2]/EEE

但如果我尝试使用

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>

    <xsl:template match="BBB/CCC[1]/DDD/../../CCC[2]/EEE">
      <XXX case="1" />
    </xsl:template>

    <xsl:template match="node()|@*">
      <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

我收到此错误:

Traceback (most recent call last):
  File "C:/.../xsltest.py", line 11, in <module>
    transform_01 = etree.XSLT(xslt_01)
  File "xslt.pxi", line 412, in lxml.etree.XSLT.__init__ (src\lxml\lxml.etree.c:152223)
lxml.etree.XSLTParseError: Cannot parse stylesheet

如果我只使用BBB / CCC [1] / DDD,则匹配有效,但不适用于&#34; ..&#34;。 我怎样才能得到父母?或者我的问题有另一种解决方案吗?

瓦尔迪

1 个答案:

答案 0 :(得分:0)

使用此XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="BBB">
    <xsl:choose>
        <xsl:when test="CCC[1]/DDD and CCC[2]/EEE">
            <XXX case="1"/>
        </xsl:when>
        <xsl:when test="CCC[1]/EEE and CCC[2]/DDD">
            <XXX case="2"/>
        </xsl:when>
        <xsl:when test="CCC[1]/EEE and CCC[2]/EEE">
            <XXX case="3"/>
        </xsl:when>
    </xsl:choose>
</xsl:template>
<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>