社区成员已将此帖子与类似的问题关联:
如何使用 VSTO (C#) 检测 PowerPoint 中的嵌套组?

只有审查方才能编辑此内容。

How to detect nested groups in PowerPoint using VSTO (C#)?

琳和 丁 0 信誉分
2025-11-05T01:54:32.1+00:00

VSTO is unable to capture nested groups within PowerPoint slides. For example, consider this structure:


Group1:

  ├── Group2:

  │   ├── Rectangle1

  │   ├── Rectangle2

  │   └── Line (connecting Rectangle1 and Rectangle2)

  └── Group3:

      ├── Rectangle3

      └── Rectangle4

show as ppt

用户的图像

show as slides.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
      <p:cSld>
        <p:spTree>
          <p:nvGrpSpPr>
            <p:cNvPr id="1" name="" />
            <p:cNvGrpSpPr />
            <p:nvPr />
          </p:nvGrpSpPr>
          <p:grpSpPr>
            <a:xfrm>
              <a:off x="0" y="0" />
              <a:ext cx="0" cy="0" />
              <a:chOff x="0" y="0" />
              <a:chExt cx="0" cy="0" />
            </a:xfrm>
          </p:grpSpPr>
          <p:grpSp>
            <p:nvGrpSpPr>
              <p:cNvPr id="14" name="group 13" />
              <p:cNvGrpSpPr />
              <p:nvPr />
            </p:nvGrpSpPr>
            <p:grpSpPr>
              <a:xfrm>
                <a:off x="1515291" y="1828800" />
                <a:ext cx="5486400" cy="3422469" />
                <a:chOff x="1515291" y="1828800" />
                <a:chExt cx="5486400" cy="3422469" />
              </a:xfrm>
            </p:grpSpPr>
            <p:grpSp>
              <p:nvGrpSpPr>
                <p:cNvPr id="12" name="group 11" />
                <p:cNvGrpSpPr />
                <p:nvPr />
              </p:nvGrpSpPr>
              <p:grpSpPr>
                <a:xfrm>
                  <a:off x="1515291" y="1828800" />
                  <a:ext cx="5486400" cy="1410789" />
                  <a:chOff x="1515291" y="1828800" />
                  <a:chExt cx="5486400" cy="1410789" />
                </a:xfrm>
              </p:grpSpPr>
              <p:sp>
                <p:nvSpPr>
                  <p:cNvPr id="4" name="rectangle 3" />
                  <p:cNvSpPr />
                  <p:nvPr />
                </p:nvSpPr>
                <p:spPr>
                  <a:xfrm>
                    <a:off x="1515291" y="1828800" />
                    <a:ext cx="2011680" cy="1410789" />
                  </a:xfrm>
                  <a:prstGeom prst="rect">
                    <a:avLst />
                  </a:prstGeom>
                </p:spPr>
                <p:style>
                  <a:lnRef idx="2">
                    <a:schemeClr val="accent1">
                      <a:shade val="50000" />
                    </a:schemeClr>
                  </a:lnRef>
                  <a:fillRef idx="1">
                    <a:schemeClr val="accent1" />
                  </a:fillRef>
                  <a:effectRef idx="0">
                    <a:schemeClr val="accent1" />
                  </a:effectRef>
                  <a:fontRef idx="minor">
                    <a:schemeClr val="lt1" />
                  </a:fontRef>
                </p:style>
                <p:txBody>
                  <a:bodyPr rtlCol="0" anchor="ctr" />
                  <a:lstStyle />
                  <a:p>
                    <a:pPr algn="ctr" />
                    <a:endParaRPr lang="zh-CN" altLang="en-US" />
                  </a:p>
                </p:txBody>
              </p:sp>
              <p:sp>
                <p:nvSpPr>
                  <p:cNvPr id="5" name="rectangle 4" />
                  <p:cNvSpPr />
                  <p:nvPr />
                </p:nvSpPr>
                <p:spPr>
                  <a:xfrm>
                    <a:off x="4990011" y="1828800" />
                    <a:ext cx="2011680" cy="1410789" />
                  </a:xfrm>
                  <a:prstGeom prst="rect">
                    <a:avLst />
                  </a:prstGeom>
                </p:spPr>
                <p:style>
                  <a:lnRef idx="2">
                    <a:schemeClr val="accent1">
                      <a:shade val="50000" />
                    </a:schemeClr>
                  </a:lnRef>
                  <a:fillRef idx="1">
                    <a:schemeClr val="accent1" />
                  </a:fillRef>
                  <a:effectRef idx="0">
                    <a:schemeClr val="accent1" />
                  </a:effectRef>
                  <a:fontRef idx="minor">
                    <a:schemeClr val="lt1" />
                  </a:fontRef>
                </p:style>
                <p:txBody>
                  <a:bodyPr rtlCol="0" anchor="ctr" />
                  <a:lstStyle />
                  <a:p>
                    <a:pPr algn="ctr" />
                    <a:endParaRPr lang="zh-CN" altLang="en-US" />
                  </a:p>
                </p:txBody>
              </p:sp>
              <p:cxnSp>
                <p:nvCxnSpPr>
                  <p:cNvPr id="8" name="Direct arrow connector 7" />
                  <p:cNvCxnSpPr>
                    <a:stCxn id="4" idx="3" />
                    <a:endCxn id="5" idx="1" />
                  </p:cNvCxnSpPr>
                  <p:nvPr />
                </p:nvCxnSpPr>
                <p:spPr>
                  <a:xfrm>
                    <a:off x="3526971" y="2534195" />
                    <a:ext cx="1463040" cy="0" />
                  </a:xfrm>
                  <a:prstGeom prst="straightConnector1">
                    <a:avLst />
                  </a:prstGeom>
                  <a:ln>
                    <a:tailEnd type="triangle" />
                  </a:ln>
                </p:spPr>
                <p:style>
                  <a:lnRef idx="1">
                    <a:schemeClr val="accent1" />
                  </a:lnRef>
                  <a:fillRef idx="0">
                    <a:schemeClr val="accent1" />
                  </a:fillRef>
                  <a:effectRef idx="0">
                    <a:schemeClr val="accent1" />
                  </a:effectRef>
                  <a:fontRef idx="minor">
                    <a:schemeClr val="tx1" />
                  </a:fontRef>
                </p:style>
              </p:cxnSp>
            </p:grpSp>
            <p:grpSp>
              <p:nvGrpSpPr>
                <p:cNvPr id="13" name="group 12" />
                <p:cNvGrpSpPr />
                <p:nvPr />
              </p:nvGrpSpPr>
              <p:grpSpPr>
                <a:xfrm>
                  <a:off x="1515291" y="3840480" />
                  <a:ext cx="4754880" cy="1410789" />
                  <a:chOff x="1515291" y="3840480" />
                  <a:chExt cx="4754880" cy="1410789" />
                </a:xfrm>
              </p:grpSpPr>
              <p:sp>
                <p:nvSpPr>
                  <p:cNvPr id="10" name="rectangle 9" />
                  <p:cNvSpPr />
                  <p:nvPr />
                </p:nvSpPr>
                <p:spPr>
                  <a:xfrm>
                    <a:off x="1515291" y="3840480" />
                    <a:ext cx="2011680" cy="1410789" />
                  </a:xfrm>
                  <a:prstGeom prst="rect">
                    <a:avLst />
                  </a:prstGeom>
                </p:spPr>
                <p:style>
                  <a:lnRef idx="2">
                    <a:schemeClr val="accent1">
                      <a:shade val="50000" />
                    </a:schemeClr>
                  </a:lnRef>
                  <a:fillRef idx="1">
                    <a:schemeClr val="accent1" />
                  </a:fillRef>
                  <a:effectRef idx="0">
                    <a:schemeClr val="accent1" />
                  </a:effectRef>
                  <a:fontRef idx="minor">
                    <a:schemeClr val="lt1" />
                  </a:fontRef>
                </p:style>
                <p:txBody>
                  <a:bodyPr rtlCol="0" anchor="ctr" />
                  <a:lstStyle />
                  <a:p>
                    <a:pPr algn="ctr" />
                    <a:endParaRPr lang="zh-CN" altLang="en-US" />
                  </a:p>
                </p:txBody>
              </p:sp>
              <p:sp>
                <p:nvSpPr>
                  <p:cNvPr id="11" name="rectangle 10" />
                  <p:cNvSpPr />
                  <p:nvPr />
                </p:nvSpPr>
                <p:spPr>
                  <a:xfrm>
                    <a:off x="4258491" y="3840480" />
                    <a:ext cx="2011680" cy="1410789" />
                  </a:xfrm>
                  <a:prstGeom prst="rect">
                    <a:avLst />
                  </a:prstGeom>
                </p:spPr>
                <p:style>
                  <a:lnRef idx="2">
                    <a:schemeClr val="accent1">
                      <a:shade val="50000" />
                    </a:schemeClr>
                  </a:lnRef>
                  <a:fillRef idx="1">
                    <a:schemeClr val="accent1" />
                  </a:fillRef>
                  <a:effectRef idx="0">
                    <a:schemeClr val="accent1" />
                  </a:effectRef>
                  <a:fontRef idx="minor">
                    <a:schemeClr val="lt1" />
                  </a:fontRef>
                </p:style>
                <p:txBody>
                  <a:bodyPr rtlCol="0" anchor="ctr" />
                  <a:lstStyle />
                  <a:p>
                    <a:pPr algn="ctr" />
                    <a:endParaRPr lang="zh-CN" altLang="en-US" />
                  </a:p>
                </p:txBody>
              </p:sp>
            </p:grpSp>
          </p:grpSp>
        </p:spTree>
        <p:extLst>
          <p:ext uri="{BB962C8B-B14F-4D97-AF65-F5344CB8AC3E}">
            <p14:creationId xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="1958624764" />
          </p:ext>
        </p:extLst>
      </p:cSld>
      <p:clrMapOvr>
        <a:masterClrMapping />
      </p:clrMapOvr>
    </p:sld>

Current behavior:

  • VSTO can only find all elements within Group1, but cannot detect that Group2 and Group3 exist as nested groups
  • The resulting JSON structure is flattened, losing the hierarchical relationship:
    
      {
    
        "group1": {
    
          "child_elements": [
    
            "rectangle1",
    
            "rectangle2",
    
            "line1",
    
            "rectangle3",
    
            "rectangle4"
    
          ]
    
        }
    
      }
    
    

Expected behavior:

  • Should detect Group2 and Group3 as nested groups within Group1
  • The JSON should preserve the hierarchical structure

Note: I've verified that python-pptx can successfully detect and parse these nested group relationships, so the data exists in the file structure.

What I've Tried

  1. Debugging in Visual Studio: Searched through available VSTO APIs but couldn't find a way to access nested groups
  2. ID matching approach: Attempted to match shape group IDs with parent group IDs, but this failed

Possible Solutions

One potential approach is to directly parse the PowerPoint XML file (similar to how python-pptx works) to extract group relationships. However, this would require:

  • Understanding the PPTX XML structure
  • Implementing custom XML parsing logic
  • Maintaining compatibility with different PowerPoint versions

Question

Is there a VSTO API or method to detect nested groups in PowerPoint that I'm missing? Or is parsing the XML directly the only viable solution?

开发人员技术 | C#
开发人员技术 | C#
一种面向对象的类型安全的编程语言,它起源于 C 语言系列,包括对面向组件的编程的支持。
0 个注释 无注释
{count} 票