0

I'm parsing this XML file: https://www.dropbox.com/s/i6hga7nvmcd6rxx/ct.cps?dl=0

From each <Reaction> tag I want its name attribute and the name attribute of its <Constant> children.

from lxml import etree

NSMAP = {"c": "http://www.copasi.org/static/schema"}

parsed = etree.parse('ct.cps')

for a in parsed.xpath("//c:Reaction", namespaces=NSMAP):
    print a.attrib['name']

I can access each of the two elements' name attributes by using the above code. However, when I'm in one iteration of the <Reaction> elements, how could I then access subelements and list them out?

I've tried this:

for a in parsed.xpath("//c:Reaction", namespaces=NSMAP):
    for b in a.xpath('Constant'):
        print b.attrib['name']

But it doesn't work.

Here's a sample of the XML

</rdf:RDF>
        </MiriamAnnotation>
      </Metabolite>
    </ListOfMetabolites>
    <ListOfReactions>
      <Reaction key="Reaction_0" name="v1" reversible="false" fast="false">
        <MiriamAnnotation>
<rdf:RDF xmlns:dcterms="http://purl.org/dc/terms/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <rdf:Description rdf:about="#Reaction_0">
    <dcterms:created>
      <rdf:Description>
        <dcterms:W3CDTF>2015-06-16T22:13:07Z</dcterms:W3CDTF>
      </rdf:Description>
    </dcterms:created>
  </rdf:Description>
</rdf:RDF>
        </MiriamAnnotation>
        <ListOfSubstrates>
          <Substrate metabolite="Metabolite_5" stoichiometry="1"/>
        </ListOfSubstrates>
        <ListOfModifiers>
          <Modifier metabolite="Metabolite_9" stoichiometry="1"/>
        </ListOfModifiers>
        <ListOfConstants>
          <Constant key="Parameter_4344" name="Kcat" value="433.724"/>
          <Constant key="Parameter_4343" name="km" value="479.617"/>
        </ListOfConstants>
        <KineticLaw function="Function_40">
          <ListOfCallParameters>
            <CallParameter functionParameter="FunctionParameter_264">
              <SourceParameter reference="Parameter_4344"/>
            </CallParameter>
            <CallParameter functionParameter="FunctionParameter_254">
              <SourceParameter reference="Metabolite_9"/>
            </CallParameter>
            <CallParameter functionParameter="FunctionParameter_258">
              <SourceParameter reference="Metabolite_5"/>
            </CallParameter>
            <CallParameter functionParameter="FunctionParameter_266">
              <SourceParameter reference="Parameter_4343"/>
            </CallParameter>
          </ListOfCallParameters>
        </KineticLaw>
      </Reaction>
      <Reaction key="Reaction_1" name="v2" reversible="false" fast="false">
        <MiriamAnnotation>
<rdf:RDF xmlns:dcterms="http://purl.org/dc/terms/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <rdf:Description rdf:about="#Reaction_1">
4
  • for b in a.xpath('.//Constant'): ? Commented Jul 5, 2015 at 18:04
  • @splash58 No that doesn't work unfortunately. Commented Jul 5, 2015 at 18:04
  • @splash58 No that doesn't work either sadly. Commented Jul 5, 2015 at 18:05
  • Instead of using dropbox link please paste the relevant contents of the xml file here (not the complete xml file) Commented Jul 5, 2015 at 18:10

1 Answer 1

2

When your parent element in an xml has a namespace, the child are also of same namespace (unless explicitely specified in the xml element), so when you are trying to search for them using XPATH , you will have to specify namespace, for children as well.

Try the following -

for a in parsed.xpath("//c:Reaction", namespaces=NSMAP):
    for b in a.xpath(".//c:Constant", namespaces=NSMAP):
        print b.attrib['name']
Sign up to request clarification or add additional context in comments.

6 Comments

Ah yes, that works. THanks. However that gives me too many answers. Id just like each constant to appear once - how would I do that?
Each constant would only appear once, there may be that many constants in the xml
No there's only about 20, that produces loads. Because there's two for loops, won't there be repeats?
No, each of the outer for loop iterates over each different reaction element, and then the inner for loop iterates over each constant element in each reaction element. So the two for loops would not lead to duplicates, but maybe there is something else in your code leading to this?
There are only 26 <Constant> tags in the whole xml, so this code must be creating duplicates
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.