Open-XML-SDK icon indicating copy to clipboard operation
Open-XML-SDK copied to clipboard

OpenXML SDK will throw exception when a percentage with % char

Open lindexi opened this issue 4 years ago • 6 comments

Before submitting an issue, please fill this out

Is this a:

  • [x] Issue with the OpenXml library

Description

When the document contains % characters, I use the OpenXML SDK to read a percentage value, an exception will be thrown.

Information

  • .NET Target: All
  • DocumentFormat.OpenXml Version: 2.12.0

https://github.com/lindexi/lindexi_gd/tree/9b506dea/RurlejileGearhuheljale

                    var background = slide.CommonSlideData.Background;
                    var backgroundProperties = background.BackgroundProperties;
                    var solidFill = backgroundProperties.GetFirstChild<SolidFill>();
                    var solidFillRgbColorModelHex = solidFill.RgbColorModelHex;
                    var alpha = solidFillRgbColorModelHex.GetFirstChild<Alpha>();
                    try
                    {
                        int alphaVal = alpha.Val;
                    }
                    catch (Exception e)
                    {
                        // Input string was not in a correct format.
                        Console.WriteLine(e);
                    }

The document:

    <p:bg>
      <p:bgPr>
        <a:solidFill>
          <a:srgbClr val="383747">
            <a:alpha val="100.00%" />
          </a:srgbClr>
        </a:solidFill>
      </p:bgPr>
    </p:bg>

Observed

The code throw exception

int alphaVal = alpha.Val;

Expected

It can convert to int value. We can convert 100% to 100000 value

lindexi avatar Jan 29 '21 09:01 lindexi

Interesting, In "ECMA-376, Fifth Edition, Part 1 - Fundamentals And Markup Language Reference", I see it should contain a percentage value:

image But, for example, if I change this Transparency value from your example on 1%

DABUXmxQwf

then <a:alpha val="100.00%" /> is changed on <a:alpha val="99000"/>.

ashahabov avatar Jan 29 '21 18:01 ashahabov

<xsd:complexType name="CT_PositiveFixedPercentage">
  <xsd:attribute name="val" type="ST_PositiveFixedPercentage" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ST_PositiveFixedPercentage">
  <xsd:union memberTypes="s:ST_PositiveFixedPercentage"/>
</xsd:simpleType>

lindexi avatar Jan 30 '21 03:01 lindexi

<xsd:simpleType name="ST_PositiveFixedPercentage">
    <xsd:restriction base="ST_Percentage">
        <xsd:pattern value="((100)|([0-9][0-9]?))(\.[0-9][0-9]?)?%"/>
    </xsd:restriction>
</xsd:simpleType>

lindexi avatar Feb 01 '21 01:02 lindexi

Maybe such string (input="100.00%") should be pre-processed here before passing into XmlConvert.ToInt32():

Int32Value.cs

...
private protected override int Parse(string input) => XmlConvert.ToInt32(input);
...

ashahabov avatar Feb 01 '21 18:02 ashahabov

The TextSpacing can add the % char too:

        <p:txBody>
          <a:bodyPr wrap="none">
            <a:spAutoFit />
          </a:bodyPr>
          <a:lstStyle />
          <a:p>
            <a:pPr>
              <a:spcBef>
                <a:spcPct val="10%" />
              </a:spcBef>
              <a:spcAft>
                <a:spcPct val="10%" />
              </a:spcAft>
            </a:pPr>
            <a:r>
              <a:rPr lang="zh-CN" altLang="en-US" dirty="0" smtClean="0" />
              <a:t>The Text</a:t>
            </a:r>
            <a:endParaRPr lang="zh-CN" altLang="en-US" dirty="0" />
          </a:p>
        </p:txBody>

The test file: The TextSpacing Text.pptx

lindexi avatar Aug 24 '22 00:08 lindexi

@adamshakhabov If you look at our implementer notes for the ISO 29500 standard (equivalent to ECMA 376), here:

MS-OI29500 2.1.1327 Part 1 Section 20.1.10.45 ST_PositiveFixedPercentage (Positive Fixed Percentage)

It says:

2.1.1327 Part 1 Section 20.1.10.45 ST_PositiveFixedPercentage (Positive Fixed Percentage) a. The standard states that ST_PositiveFixedPercentage is read and written as a percent with a trailing percent sign. Office will read percentages formatted with a trailing percent sign or formatted as 1000th of a percent without a trailing percent sign, but only write percentages as 1000th's of a percent without a trailing percent sign.

This at least explains Office behavior here.

@lindexi Regarding the alpha class, it does look like it should get and set the Val property as an int. We will investigate this to handle the conversion from the string form.

tomjebo avatar Aug 24 '22 16:08 tomjebo