Working with OneNote Page Content via the Graph AP

2019-07-08 10:21发布

问题:

I have a number of issues when working with OneNote via the graph api.

I understand that what OneNote uses is not straight html and they need to convert it back and forward for the API... but this would not appear to be that complex a task.

I am processing tags in the content and need to be able to update the tag element. It is fine except for where I have a list of items (p or li) tags where there are indents.

UPDATED

If there are items like this in my onenote

Dont have the rights to embed an image... so here is the link https://xomq6w.ch.files.1drv.com/y4mc-mJZRhkI5c_fvOAbHGOnzEKVNKgxTHLop-OHfNofncLcC2gUc_Z_aYi0sgrc3hxIxxWpnvwRFc7p-reL5mX8J5pp1ePaY0V2McibdocMTplud7lxcso0EwAGJpHpBkcyLbcsLxDUpoYZ9T5XgCCxxmfUwQhHFPFQdFscfQoDPp7ZA-vCNbErgqyz0FK7prVaeMjs8LpiftMKu6-Xcv7Rg?width=160&height=541&cropmode=none

I hit the graph api to get the content with the following url via the graph api explorer

GET - https://graph.microsoft.com/beta/users/myname/onenote/pages/0-c9861926a1e8080518ca3750afa63800!1-2B303C571455A20B!102505/content?includeIDs=true

the html that comes back will look like this (note that the indents are not there)

<body data-absolute-enabled="true" style="font-family:Calibri;font-size:11pt">
    <div id="div:{f115c5ea-0481-0f03-31aa-07b94321c323}{65}" style="position:absolute;left:264px;top:139px;width:624px">
        <p id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{67}" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 1</p>
        <p id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{74}" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 2</p>
        <p id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{71}" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 2a</p>
        <p id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{73}" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 2b</p>
        <p id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{76}" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 3</p>
    </div>
</body>

And if I patch the ones that have child items like this to set ids (leaving the id in there... turns it into a permanent data-id) for later updates or even to close a tag:

PATCH - https://graph.microsoft.com/beta/users/myname/onenote/pages/0-c9861926a1e8080518ca3750afa63800!1-2B303C571455A20B!102505/content?includeIDs=true

[
  {
    'target':'p:{f115c5ea-0481-0f03-31aa-07b94321c323}{74}',
    'action':'replace',
    'content':'<p id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{74}" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 2</p>'
  }
]

The update will be processed and then the content will be updated to this:

Image here: https://kw9psa.ch.files.1drv.com/y4mplcvzocTmhN9DZBpFt4Sic3AOpxe2Ik4r7VX_0Joxs5ay9woTUYZufKSr0ojcfwQckovsJv5__fSrDx1GqWK9cFa2yQ7uFPE8JQOBwPyYn6PQZHDMM4N9JB4IXF4Rs7dIDoqa0XYfjz93qGiI97Ais99l04QxWZyV1Og5eXRguUYlBoNTwXIuzFEbKZfA03mt_ynxXCjbM7CFHYP99_QgQ?width=160&height=134&cropmode=none

<body data-absolute-enabled="true" style="font-family:Calibri;font-size:11pt">
    <div id="div:{f115c5ea-0481-0f03-31aa-07b94321c323}{65}" style="position:absolute;left:264px;top:139px;width:624px">
        <p id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{67}" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 1</p>
        <p id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{71}" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 2a</p>
        <p id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{73}" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 2b</p>
        <p id="p:{78cb2ca5-efec-4e6f-a763-12e9cac6a2b5}{2}" lang="en-US" data-tag="to-do" data-id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{74}" style="margin-top:0pt;margin-bottom:0pt">Item 2</p>
        <p id="p:{f115c5ea-0481-0f03-31aa-07b94321c323}{76}" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 3</p>
    </div>
</body>

The same essentially happens for nested ul/ol items... I also tried replacing the whole list instead of individual items, but the api call errors out with no additional information. Nested bulleted lists also seem to lose the parent bullet.

I have tried batching all updates for all items, doing one at a time, reversing the order.

Funnily enough if I do an insert then the text indents and order are retained, but there is no delete/remove patch to clean out the old text... e.g.

[
  {
    'target':'p:{56d579c0-1203-0224-0587-6fe03fb82539}{34}',
    'action':'insert',
    'position':'before',
    'content':'<p data-id="My_own_id" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 1</p>'
  },
  {
    'target':'p:{56d579c0-1203-0224-0587-6fe03fb82539}{34}',
    'action':'<tried replace or delete/remove hoping it was undocumented>',
    'content':'<tried blank or just a span>'
  }
]

Other issues include

  • tables losing their show gridlines properties
  • tags with no text not returning or even just disappearing if I update any text on the page

Partial Answer

Here is a partial answer for the non bulletted list issue... thanks to codeye for pointing me in the right direction.

By inserting my element before the existing one it retains the order.

[
  {
    'target':'p:{20781e6d-ba99-4fca-9994-622720cad7f8}{249}',
    'action':'insert',
    'position':'before',
    'content':'<p data-id="test" data-tag="to-do" style="margin-top:0pt;margin-bottom:0pt">Item 2</p>'
  }
]

Then removing the old one with the following it looks to retain the formatting. And as it is an empty div OneNote doesn't add the element.

[
  {
    'target':'p:{20781e6d-ba99-4fca-9994-622720cad7f8}{249}',
    'action':'replace',
    'content':'<div></div>'
  }
]

回答1:

A solution for table borders

When work with tables use border attribute instead of style.

API returns you a table with borders as <table style="border:1px solid;border-collapse:collapse">...</table>. Use table.style.border to find if there is a border (it can be 1px or 0px). To set border for the table use border attribute: <table border="1">...</table>.

The border attribute for td will be ignored.



回答2:

To the specific problem with the to-do list I can confirm the issue where the indented items shift up and "detach" from the element being updated.
It looks like the only reliable way to update a list with indents is to replace the entire list (a similar limitation is placed on tables).
In your example all 5 paragraphs seem to need to be updated to maintain alignment.
If that doesn't work try replacing the surrounding div

 [
      {
        'target':'div:{9dfa7be6-2de0-b802-01ae-20c164255f9d}{30}',
        'action':'replace',
        'content':'<div><p data-tag="to-do">Item 1</p>
                   <div><p data-tag="to-do">Item 2</p>
                        <ul>
                           <p data-tag="to-do:completed">Item 2a</p>
                           <p data-tag="to-do:completed">Item 2b</p>
                       </ul>
                   <div><p data-tag="to-do">Item 3</p>
                   <div><p data-tag="to-do">Item 4</p>
                  </div>'
      }    
]

As to how to remove an element the below should work

[{
      'target': 'p:{f5837c83-d816-4337-ab6d-a52abde869a6}{13}',
      'action': 'replace',
      'content': '<br/>'
    }]

This will not work in the middle of a list as you get a vertical gap.