14
I have the following XML (simplified):
<produto refid="cat01" idprod="tv01">
<marca>xxx</marca>
<modelo>xxxx</modelo>
<genero>xxx</genero>
</produto>
<v:utilizador iduser="U00000" comercial="12344" loja="xxxxx">
<nome>xxxxx</nome>
<contacto>94xxxxxx</contacto>
<email>loja@xxxxxxx</email>
<morada>xxxxxx</morada>
<localidade>xxxxxx</localidade>
<cesto>
<encomenda refidprod="rlg04" estado="enviado"/>
<encomenda refidprod="tv04" estado="enviado"/>
</cesto>
</v:utilizador>
<u:utilizador iduser="U00003" comercial="" loja="">
<nome>xxxxx</nome>
<contacto>93xxxxxx</contacto>
<email>xxxxxxxx</email>
<morada>xxxxxx</morada>
<localidade>xxxxx</localidade>
<cesto>
<encomenda refidprod="tlf04" estado="em processo"/>
</cesto>
</u:utilizador>
And I have to write a Python code that shows all products purchased by a particular user. I did the following:
from lxml import etree
u={'u':'Utilizador'} ##Declaração do namespace
file = "marketplace.xml"
treeDoc = etree.parse(file)
nome=str(raw_input('Insira o nome: '))
print("Cesto de " + nome)
elemList = treeDoc.xpath("//produto[./@idprod=//utilizadores/u:utilizador[./nome='"+ nome +"']/cesto/encomenda/@refidprod]/marca", namespaces=u)
for elem in elemList:
print("Item: ", elem.get("idprod"))
nameList = elem.xpath("produto")
print(nameList[0].tag, ": ", nameList[0].text)
Just nothing comes back to me. Can anyone tell me what the problem is? Another question: How do I xpath return the two namespaces without having to querys different?
I tested it here, and it worked. I had to adapt his example, because: 1. The user U00003 did not buy tv01, so in this example it was not to return anything at all; 2. I put the missing elements (xml root and element
utilizadores
). As you stated in your xml the namespaceu
? That’s how:xmlns:u="Utilizador"
? If the xmlns in the file is one and the code is another, it does not error, but returns nothing. When returning two namespaces, I’m not sure which is the best way, but should involve aor
or a Union (|
).– mgibsonbr
P.S. The xpath worked, the
for
not below. You are selecting the brand, not the product...– mgibsonbr
Yes I declared as you said, xmlns:u='User'. I didn’t understand the for part, how do I return the tag then?
– fedora
The mark is rather being returned, is that the
for
tries to catchidprod
which is an attribute ofproduto
(that is just above the mark in the hierarchy), and then tries to catch elementsproduto
, which in their example are not sub-elements ofmarca
. When to the problem of not returning anything, would you have a more complete example of input, maybe a real xml file posted in Pastebin, for example? Because I can’t reproduce your problem, with me your xpath worked perfectly...– mgibsonbr
Hi, thanks for the help but I already figured out the error, in my xpath declaration I was asking for the brand when I should actually ask for the idprod to match the refidprod in the user’s basket. 

elemList = treeDoc.xpath("//produto[./@idprod=//utilizadores/u:utilizador[./nome='"+ nome +"']/cesto/encomenda/@refidprod]", namespaces=u)

for elem in elemList:
 print("Item: ", elem.get("idprod"))
 nameList = elem.xpath("marca")
 print(namelist[0].tag, ": ", namelist[0].text) . Thanks just the same
– fedora
Good! But before closing the question, explain one thing to me: why there are two namespaces
u
andv
when the structure of its users seems to me identical?– mgibsonbr
There are two namespaces that were to differentiate users (u:'users') from sellers (v:'sellers'). This xml was an adaptation of an online market where there were categories, products and users/sellers.
– fedora