pythonxmlelementtreexincludexpointer

Using Python ElementTree/ElementInclude and xpointer to access included XML files


I have a 'main.xml' file that includes 2 'sub_x.xml' file. The include lines are using 'xpointer' to only point/include specific tags of the include xml's. When I use ElementTree to determine if this worked correctly, it shows that the whole 'sub' xml files are being included and not just the tags I want. I am not sure if I am using xpointer incorrectly or ElementTree or ElementInclude does not support this. Here are the files:

------'main.xml'--------

`<?xml version='1.0' encoding='utf-8'?>
<ModelInfo xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include href="sub_1.xml" xpointer="xpointer(//ModelInfo/Model)" parse="xml" />
    <xi:include href="sub_2.xml" xpointer="xpointer(//ModelInfo/Model)" parse="xml" />  
</ModelInfo>`

-------'sub_1.xml'------

`<?xml version="1.0" ?>
<ModelInfo>
  <Model ModelName="glow">
    <Variables>
     <Variable Alias="glow_val" Input="False" Output="True" />
    </Variables>
  </Model>
</ModelInfo>`

-------'sub_2.xml'------

`<?xml version='1.0' encoding='utf-8'?>
<ModelInfo>
  <Model ModelName="sirpwr_b_supply8v1">
   <Variables>
    <Variable Alias="sirpwr_a_supplyecu_Snsr8vIstat" Input="True" Output="False" />
   </Variables>
  </Model>
</ModelInfo>`

I would like 'main.xml' to appear to ElementTree as:

`<?xml version='1.0' encoding='utf-8'?>
<ModelInfo xmlns:xi="http://www.w3.org/2001/XInclude">
  <Model ModelName="glow">
    <Variables>
     <Variable Alias="glow_val" Input="False" Output="True" />
    </Variables>
  </Model>
  <Model ModelName="sirpwr_b_supply8v1">
    <Variables>
     <Variable Alias="sirpwr_a_supplyecu_Snsr8vIstat" Input="True" Output="False" />
     <Variable Alias="sirpwr_b_supply8v1_qstat" Input="False" Output="True" />
   </Variables>
   </Model>
</ModelInfo>`

The script I am running to load the XML files and test is:

`tree = ElementTree.parse('main.xml')
root = tree.getroot()
ElementInclude.include(root)
for element in root:
    print element.tag`

xpointer is not working because 'ModelInfo' is being copied over from the 'sub_x' xml files.


Solution

  • ElementInclude does not support all of XInclude. The xpointer attribute on the <include> element is ignored.

    It does work the way you want it with lxml and the xinclude() method:

    from lxml import etree 
    
    tree = etree.parse('main.xml')
    tree.xinclude()
    print etree.tostring(tree)
    

    Note that the XPointer xpointer() scheme never reached the status of W3C Recommendation (it's still just a working draft). It has been implemented in libxml2 (the C library behind lxml) but almost nowhere else.