Python pptx:“;显示与图表重叠的图例”;

Python pptx:“;显示与图表重叠的图例”;,python,legend,python-pptx,Python,Legend,Python Pptx,我正在使用Office2007。 我发现我是否想在office2007中显示与图表重叠的图例。 XML应该如下所示 `-<c:legend> <c:overlay val="1"/>` `-<c:legend> <c:overlay/>` `- ` 但无论我使用python pptx中的API‘chart.legend.include_in_layout=True’,还是将其保留为默认值。生成的XML将始终如下所示 `-&l

我正在使用Office2007。 我发现我是否想在office2007中显示与图表重叠的图例。 XML应该如下所示

`-<c:legend>
   <c:overlay val="1"/>` 
`-<c:legend>
   <c:overlay/>` 
`-
` 
但无论我使用python pptx中的API‘chart.legend.include_in_layout=True’,还是将其保留为默认值。生成的XML将始终如下所示

`-<c:legend>
   <c:overlay val="1"/>` 
`-<c:legend>
   <c:overlay/>` 
`-
` 
如果没有val=1,office2007将无法正确显示格式。 如何强制python pptx编写val=1?谢谢。

解释 简而言之,
True
值没有明确设置(与
False
相反),因为
True
对应于
overlay
val
属性的默认值

为了更详细地解释它,您可以遵循python pptx层次结构,如下所示:
overlay
is-To(所有overlay-oxml元素都是从CT\u-Boolean实例化的)。然后通过映射实际的
val
参数,并使用默认值
True
进行定义:

class CT_Boolean(BaseOxmlElement):
    """
    Common complex type used for elements having a True/False value.
    """
    val = OptionalAttribute('val', XsdBoolean, default=True)
现在,当将可选属性设置为其默认值时,它实际上被跳过/删除,如您所见,
if value==self.\u default

class OptionalAttribute(BaseAttribute):
    """
    Defines an optional attribute on a custom element class. An optional
    attribute returns a default value when not present for reading. When
    assigned |None|, the attribute is removed.
    """

    @property
    def _setter(self):
        def set_attr_value(obj, value):
            if value == self._default:
                if self._clark_name in obj.attrib:
                    del obj.attrib[self._clark_name]
                return
            str_value = self._simple_type.to_xml(value)
            obj.set(self._clark_name, str_value)
        return set_attr_value
修复-提供自定义CT_布尔类 在需要使用覆盖之前,将这些线添加到某个位置。它将用自定义的
CT\u Boolean\u NoDefault
类覆盖python pptx
overlay
映射:

from pptx.oxml import register_element_cls
from pptx.oxml.xmlchemy import BaseOxmlElement, OptionalAttribute
from pptx.oxml.simpletypes import XsdBoolean


class CT_Boolean_NoDefault(BaseOxmlElement):
    """
    Common complex type used for elements having a True/False value with no
    default value.
    """
    val = OptionalAttribute('val', XsdBoolean)

register_element_cls('c:overlay', CT_Boolean_NoDefault)
这对我起了作用,最终我得到:

<c:legend>
    <c:overlay val="1"/>
</c:legend>
其次,修改
pptx/oxml/__init__uuu.py
以添加新的bool类:

from .chart.shared import (
    CT_Boolean, CT_Double, CT_Layout, CT_LayoutMode, CT_ManualLayout,
    CT_NumFmt, CT_Tx, CT_UnsignedInt, CT_Boolean_NoDefault
)
register_element_cls('c:overlay', CT_Boolean_NoDefault)
第三,修改
pptx/oxml/\uuuuu init\uuuuuu.py
以将
覆盖
元素的映射更改为新的bool类:

from .chart.shared import (
    CT_Boolean, CT_Double, CT_Layout, CT_LayoutMode, CT_ManualLayout,
    CT_NumFmt, CT_Tx, CT_UnsignedInt, CT_Boolean_NoDefault
)
register_element_cls('c:overlay', CT_Boolean_NoDefault)
更好的解决方案
如果你有时间,请提交一张罚单,这样它可能会成为一个永久的解决方案。如果有时间,他会读这篇文章。也许还有更好的解决办法,我完全错过了一些东西。

@pansen的分析是正确的。在您的案例中,有另一种方法可以使其工作,重量可能会轻一点:

def include_in_layout(legend):
    legend_element = legend._element
    overlay = legend_element.get_or_add_overlay()
    overlay.set('val', '1')
这似乎是该版本PowerPoint与ISO/IEC 29500规范的局部不一致。正如pansen正确指出的那样,缺失的
val
属性将被解释为与
val=1
True
)相同。我有兴趣发现这种不符合的范围有多广,也就是说,有哪些其他元素表现出这种相同的行为。PowerPoint中经常使用
CT\u Boolean
类型,例如粗体、斜体、彩色、平滑等等。因此,需要谨慎地应用“补偿”修复,以避免报告其他元素的错误结果


我想我会接受pansen的提示,只为这个元素使用一个专门的元素类。对于没有val属性的元素,它仍将报告
True
,这将与此版本PowerPoint上观察到的行为不一致;但是,假设其他版本的行为正确(根据规范),不一致性将被本地化,并且至少将
True
指定给该属性将使图例以您想要的方式显示。

优秀的分析pansen!:)这似乎是该版本PowerPoint中与ISO/IEC规范的不幸背离。我喜欢你的解决方案,因为它将Word在这一点上的明显不符合项的补偿本地化;更改为
CT\u Boolean
本身具有深远的影响,因为它被频繁使用。指定默认值会更改读取行为和写入行为,这样
将报告legend.overlay与
True的
。所以“修复”应该尽可能本地化,甚至可能会在读取时报告某些版本的错误结果。。。。但我会为它做一个案例,看看在下一个版本中是否会有一个补偿补丁。干得好!:)今天发布的v0.6.5中出现了一个可避免此问题的补偿更改。@scanny,太棒了。非常感谢您的工作-python pptx是一个很棒的软件包!不幸的是,我还没有时间仔细研究ISO/IEC规范以及它与当前问题的关系(稍后我会再讨论)。据我所知,Powerpoint似乎偏离了规范,而python pptx正确地实现了
overlay
元素的默认值。到目前为止这是正确的吗?我想说python pptx对CT_Boolean的实现产生的XML是规范允许的,并且在许多情况下与PowerPoint生成的XML保持一致。我们可以称这种风格为“隐式真实”。例如,
是为真而写,
是为假而写。读取时,
都被解释为True。这有点紧凑,但需要引用外部“默认”值。显然,在这种情况下,微软的代码的默认值是错误的。但对我们来说,把它说清楚并不是一个坏主意:)