简体   繁体   中英

Delete nodes from XML file in SQL Server

I have an XML file, exported from Excel, that is stored in an XML column in a table in SQL Server. The Excel file had many worksheets, and I only want to store a few of them. Is there a way to delete nodes that don't have the name I want to keep, similar to NOT IN ?

The XML file has this header:

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">

This is the basic structure of the XML:

<Workbook>
  <DocumentProperties>
  </DocumentProperties>
  <ExcelWorkbook>
  </ExcelWorkbook>
  <Styles>
    <Style>
    </Style>
  </Styles>
  <Worksheet ss:Name="Worksheet1">
    <Table>
      <Column.../>
      <Column.../>
      <Column.../>
      <Row>
        <Cell.../>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
        <Cell.../>
      </Row>
      ...
    </Table>
  </Worksheet>

and the node is repeated several times. Let's say I only want to keep "Worksheet3","Worksheet4", and "Worksheet8". How could I do that? I think I would want to use update and modify() in this case, similar to this question . The only difference is that I want to keep certain values, and delete the rest.

Try it like this:

DECLARE @xml XML=
'<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">
  <DocumentProperties>
  </DocumentProperties>
  <ExcelWorkbook>
  </ExcelWorkbook>
  <Styles>
    <Style>
    </Style>
  </Styles>
  <Worksheet ss:Name="Worksheet1">
    <Table>
      <Column/>
      <Column/>
      <Column/>
      <Row>
        <Cell.../>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
      </Row>
    </Table>
  </Worksheet>
  <Worksheet ss:Name="Worksheet2">
    <Table>
      <Column/>
      <Column/>
      <Column/>
      <Row>
        <Cell.../>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
      </Row>
    </Table>
  </Worksheet>
  <Worksheet ss:Name="Worksheet3">
    <Table>
      <Column/>
      <Column/>
      <Column/>
      <Row>
        <Cell.../>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
        <Cell><Data>...</Data></Cell>
      </Row>
    </Table>
  </Worksheet>
</Workbook>';

SET @xml.modify('declare namespace dflt="urn:schemas-microsoft-com:office:spreadsheet";
                 declare namespace ss="urn:schemas-microsoft-com:office:spreadsheet"; 
                 delete /dflt:Workbook/dflt:Worksheet[@ss:Name="Worksheet2"]');

SELECT @xml;

You can combine many filter expressions with "or"...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM