Can't figure out why script isn't going any further - python

I have this function called zms_add_bridge that calls a function called xmlbuilder. xmlbuilder creates a global variable called xml and populates it with stuff.
When zms_add_bridge is called, it prints "here" to say that it's gotten at least that far in the script. Then, it calls xmlbuilder, which prints "xml1" along with the xml output to say that it's at least gotten that far in the script.
The issue is that once xmlbuilder exits and returns to zms_add_bridge, the script seems to die. xml is a global variable, so it should print "yes", but it's not even printing "no".
I even tried to return xml at the end of xmlbuilder to see if that would work, but it didn't (and even still, that'd be redundant since xml was declared globally, wouldn't it?)
Any clues? I'm lost.
def xmlbuilder(requestType,xbra):
global xmlbuild
global xmlbuild__request
global xmlbuild__requestElement
global xmlbuild__requestElementAttribute
global xml
xmlbuild = etree.Element("OSS", attrib={"{"+xsi+"}schemaLocation":schema}, nsmap={'xsi':xsi, None:xmlns})
xmlbuild__request = etree.SubElement(xmlbuild, "Request")
etree.SubElement(xmlbuild__request, "RequestType").text = requestType
etree.SubElement(xmlbuild__request, "RequestMode").text = "online"
etree.SubElement(xmlbuild__request, "SessionID").text = session_id
etree.SubElement(xmlbuild__request, "operName").text = apiUser
etree.SubElement(xmlbuild__request, "Version").text = version
etree.SubElement(xmlbuild__request, "Overwrite").text = "false"
xmlbuild__requestElement = etree.SubElement(xmlbuild, "RequestElement")
for index, data in xbra.items():
for key in data:
xmlbuild__requestElementAttribute = etree.SubElement(xmlbuild__requestElement, "Attribute")
etree.SubElement(xmlbuild__requestElementAttribute, "Name").text = "%s" % key
etree.SubElement(xmlbuild__requestElementAttribute, "Value").text = "%s" % data[key]
xml = etree.tostring(xmlbuild, encoding="UTF-8", pretty_print=True, xml_declaration=True)
if debug >= 1:
print "\nDEBUG: Generated XML for transmission\n"
print xml
print "xml1: " + xml
def zms_add_bridge(fsan,vlanId,maxUnicast,secure):
if debug >= 3:
print "\nDEBUG: Function: zms_add_bridge\n"
print "\nDEBUG: Get GPON parameters of ONT\n"
xbra = defaultdict(list)
xbra[1] = {'Filter_Type': 'GponOnuPhysical'}
xbra[2] = {'Filter_Condition': 'Device_Id=' + device_Handle_Id}
xbra[3] = {'Filter_Condition': 'serialNoVendorId=ZNTS'}
xbra[4] = {'Filter_Condition': 'serialNoVendorSpecificHex=' + fsan}
if debug >= 4:
print "\nDEBUG: Dictionary\n"
for index, data in xbra.items():
for key in data:
print "Index: %s: Key: %s, Value: %s" % (index, key,data[key])
print "here"
xmlbuilder("list",xbra)
if xml:
print "yes"
else:
print "no"
Output:
here
xml1: <?xml version='1.0' encoding='UTF-8'?>
<OSS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zhone.com/OSSXML" xsi:schemaLocation="http://www.zhone.com/OSSXML ossxml.xsd">
<Request>
<RequestType>list</RequestType>
<RequestMode>online</RequestMode>
<SessionID>0.379081153249641</SessionID>
<operName>boss</operName>
<Version>2.5.1</Version>
<Overwrite>false</Overwrite>
</Request>
<RequestElement>
<Attribute>
<Name>Filter_Type</Name>
<Value>GponOnuPhysical</Value>
</Attribute>
<Attribute>
<Name>Filter_Condition</Name>
<Value>Device_Id=2</Value>
</Attribute>
<Attribute>
<Name>Filter_Condition</Name>
<Value>serialNoVendorId=ZNTS</Value>
</Attribute>
<Attribute>
<Name>Filter_Condition</Name>
<Value>serialNoVendorSpecificHex=03739175</Value>
</Attribute>
</RequestElement>
</OSS>

Related

Schema validation failed; XML does not comply with UBL 2.1 standards in line with ZATCA specifications

I am trying to use validate my xml with UBL 2.1 standards in line with Saudi Arabia ZATCA(Zakat, Tax and Customs Authority) specifications.The url of this validatoe : https://sandbox.zatca.gov.sa/TestXML .But I can't validate that as my xml looking great but I don't understand what's going wrong .I used python json2xml package for creating xml.This package generate xml from json.
Erros list what I am getting from ZATCA XML Validator:
category : XSD_SCHEMA_ERROR
code :SAXParseException
message : Schema validation failed; XML does not comply with UBL 2.1 standards in line with ZATCA specifications
Here is my Xml code:
<?xml version="1.0" ?>
<Invoice>
<ProfileID>reporting:1.0</ProfileID>
<ID>INV004</ID>
<UUID>fd5a7cc4-2316-49ee-ac07-6f4be4be3731</UUID>
<IssueDate>2022-08-13</IssueDate>
<IssueTime>23:46:07</IssueTime>
<InvoiceTypeCode>388</InvoiceTypeCode>
<InvoiceTypeCodeName>0101001</InvoiceTypeCodeName>
<DocumentCurrencyCode>SAR</DocumentCurrencyCode>
<TaxCurrencyCode>SAR</TaxCurrencyCode>
<Note/>
<OrderReference>
<ID/>
</OrderReference>
<ContractDocumentReference>
<ID/>
</ContractDocumentReference>
<AdditionalDocumentReference>
<UUID>4</UUID>
<PIH>
<Attachment>
<EmbeddedDocumentBinaryObject>ET05jV7roub7D66wOAQ49TQ8mCkyldhmH7B8CV3Rc6g=</EmbeddedDocumentBinaryObject>
</Attachment>
</PIH>
<QR>
<Attachment>
<EmbeddedDocumentBinaryObject>5D6ZU7f6nb+s1szmMw46l4NZ7yTy0p1wi0ZUMsdQWBE=</EmbeddedDocumentBinaryObject>
</Attachment>
</QR>
</AdditionalDocumentReference>
<Signature>
<ID>urn:oasis:names:specification: ubl:signature:Invoice</ID>
<SignatureMethod>urn:oasis:names:specification:ubl:dsig:enveloped: xades</SignatureMethod>
</Signature>
<AccountingSupplierParty>
<Party>
<PartyLegalEntity>
<RegistrationName>Altaf Miazee</RegistrationName>
</PartyLegalEntity>
<PartyIdentification>
<ID/>
</PartyIdentification>
<PartyTaxScheme>
<CompanyID>300600363600003</CompanyID>
</PartyTaxScheme>
<PostalAddress>
<Country>
<IdentificationCode>BD</IdentificationCode>
</Country>
<AdditionalStreetName>Altafbari</AdditionalStreetName>
<StreetName>dhaka</StreetName>
<BuildingNumber>1233</BuildingNumber>
<PlotIdentification>1233</PlotIdentification>
<CityName>Dhaka</CityName>
<PostalZone>12302</PostalZone>
<CountrySubentity>Dhaka</CountrySubentity>
<CitySubdivisionName>miazee</CitySubdivisionName>
</PostalAddress>
</Party>
</AccountingSupplierParty>
<AccountingCustomerParty>
<Party>
<PartyLegalEntity>
<RegistrationName>Hosen MD Altaf</RegistrationName>
</PartyLegalEntity>
<PartyIdentification>
<ID>398765409876333</ID>
</PartyIdentification>
<PartyTaxScheme>
<CompanyID>398765409876333</CompanyID>
</PartyTaxScheme>
<PostalAddress>
<StreetName>الملك سلمان</StreetName>
<AdditionalStreetName>الملك سلمان</AdditionalStreetName>
<BuildingNumber>1234</BuildingNumber>
<PlotIdentification>1234</PlotIdentification>
<CityName>dhaka</CityName>
<PostalZone>12234</PostalZone>
<CountrySubentity>Dhaka</CountrySubentity>
<CitySubdivisionName>الملك سلمان</CitySubdivisionName>
<Country>
<IdentificationCode>BD</IdentificationCode>
</Country>
</PostalAddress>
</Party>
</AccountingCustomerParty>
<Delivery>
<ActualDeliveryDate>2022-08-25</ActualDeliveryDate>
<LatestDeliveryDate/>
</Delivery>
<PaymentMeans>
<PaymentMeansCode>10</PaymentMeansCode>
<PayeeFinancialAccount>
<PaymentNote/>
</PayeeFinancialAccount>
</PaymentMeans>
<AllowanceCharge>
<TaxCategory>
<ID>S</ID>
<Percent>0.0</Percent>
<TaxScheme>
<ID>VAT</ID>
</TaxScheme>
</TaxCategory>
<ChargeIndicator>False</ChargeIndicator>
<MultiplierFactorNumeric>52.1</MultiplierFactorNumeric>
<Amount>0.00</Amount>
<AmountcurrencyID>SAR</AmountcurrencyID>
<BaseAmount>164263.68</BaseAmount>
<BaseAmountcurrencyID>SAR</BaseAmountcurrencyID>
</AllowanceCharge>
<LegalMonetaryTotal>
<LineExtensionAmount>164263.68</LineExtensionAmount>
<LineExtensionAmountCurrencyID>SAR</LineExtensionAmountCurrencyID>
<AllowanceTotalAmount>0.00</AllowanceTotalAmount>
<AllowanceTotalAmountcurrencyID>SAR</AllowanceTotalAmountcurrencyID>
<TaxExclusiveAmount>146664.00</TaxExclusiveAmount>
<TaxExclusiveAmountcurrencyID>SAR</TaxExclusiveAmountcurrencyID>
<TaxInclusiveAmount>164263.68</TaxInclusiveAmount>
<TaxInclusiveAmountcurrencyID>SAR</TaxInclusiveAmountcurrencyID>
<PrepaidAmount/>
<PrepaidAmountcurrencyID>SAR</PrepaidAmountcurrencyID>
<PayableAmount>164263.68</PayableAmount>
<PayableAmountcurrencyID>SAR</PayableAmountcurrencyID>
</LegalMonetaryTotal>
<TaxTotal>
<TaxAmount>17599.68</TaxAmount>
<VatAmountCurrency>SAR</VatAmountCurrency>
<VatAmountInAccountingCurrency>17599.68</VatAmountInAccountingCurrency>
<CurrencyForVatAmountInAccountingCurrency>SAR</CurrencyForVatAmountInAccountingCurrency>
<TaxSubtotal>
<TaxableAmount>146664.0</TaxableAmount>
<TaxableAmountcurrencyID>SAR</TaxableAmountcurrencyID>
<TaxCategory>
<ID>E</ID>
<Percent>1</Percent>
<TaxExemptionReasonCode>TYIEWE</TaxExemptionReasonCode>
<TaxExemptionReason>lksdkskak</TaxExemptionReason>
<TaxScheme>
<ID>10.12</ID>
</TaxScheme>
</TaxCategory>
<TaxAmountcurrencyID>SAR</TaxAmountcurrencyID>
</TaxSubtotal>
<TaxAmountcurrencyID>SAR</TaxAmountcurrencyID>
</TaxTotal>
<InvoiceLine>
<item>
<ID>1</ID>
<InvoicedQuantity>12</InvoicedQuantity>
<InvoicedQuantityUnitCode>nos</InvoicedQuantityUnitCode>
<LineExtensionAmount>146664.0</LineExtensionAmount>
<LineExtensionAmountcurrencyID>SAR</LineExtensionAmountcurrencyID>
<AllowanceCharge>
<ChargeIndicator>False</ChargeIndicator>
<MultiplierFactorNumeric>0.0</MultiplierFactorNumeric>
<Amount>0</Amount>
<AmountcurrencyID>SAR</AmountcurrencyID>
<BaseAmount>146664.0</BaseAmount>
<BaseAmountcurrencyID>SAR</BaseAmountcurrencyID>
</AllowanceCharge>
<TaxTotal>
<TaxAmount>17599.68</TaxAmount>
<TaxAmountcurrencyID>SAR</TaxAmountcurrencyID>
<RoundingAmount>164263.68</RoundingAmount>
<RoundingAmountcurrencyID>SAR</RoundingAmountcurrencyID>
</TaxTotal>
<Item>
<Name>altaf</Name>
<BuyersItemIdentification>
<ID/>
</BuyersItemIdentification>
<SellersItemIdentification>
<ID>ITM9</ID>
</SellersItemIdentification>
<StandardItemIdentification>
<ID/>
</StandardItemIdentification>
<ClassifiedTaxCategory>
<ID>2</ID>
<Percent>12.00</Percent>
<TaxScheme>
<ID>VAT</ID>
</TaxScheme>
</ClassifiedTaxCategory>
</Item>
<Price>
<PriceAmount>12222.00</PriceAmount>
<PriceAmountschemeID>SAR</PriceAmountschemeID>
<AllowanceCharge>
<ChargeIdicator>False</ChargeIdicator>
<Amount>0</Amount>
<AmountcurrencyID>SAR</AmountcurrencyID>
<BaseAmount>164263.68</BaseAmount>
<BaseAmountcurrencyID>SAR</BaseAmountcurrencyID>
</AllowanceCharge>
<BaseQuantity>12</BaseQuantity>
<BaseQuantityUnitCode/>
</Price>
</item>
</InvoiceLine>
</Invoice>
Here is the python code I wrote for creating XML:
def download_invoice_xml(request, invoice_type, invoice_no):
in_data = InvoiceReport.objects.filter(invoice_type=invoice_type, invoice_number=invoice_no)
for inv in in_data:
jsonData = inv.invoice_data
mode = inv.creation_mode
# Issuetime = jsonData['IssueTime']
# d1 = datetime.strptime(Issuetime, "%Y-%m-%dT%H:%M:%S")
# dt_to_string = d1.strftime('%d-%m-%Y %H:%M:%S')
# jsonData['IssueTime'] = dt_to_string
#
# Issuedate = jsonData['IssueDate']
# d2 = datetime.strptime(Issuedate, "%Y-%m-%d")
# dt_to_string2 = d1.strftime('%d-%m-%Y')
# jsonData['IssueDate'] = dt_to_string2
if jsonData.get('AllowanceCharge').get('ChargeIndicator') == 0:
jsonData['AllowanceCharge']['ChargeIndicator'] = False
for i in jsonData.get('InvoiceLine'):
if i.get('AllowanceCharge').get('ChargeIndicator') == 0:
i['AllowanceCharge']['ChargeIndicator'] = False
if i.get('Price').get('AllowanceCharge').get('ChargeIndicator') == 0:
i['Price']['AllowanceCharge']['ChargeIndicator'] = False
xml_output = json2xml.Json2xml(jsonData, wrapper="Invoice", pretty=True, attr_type=False).to_xml()
now = datetime.now()
if xml_output:
response = HttpResponse(xml_output, content_type='application/xml')
xml_date = jsonData['IssueDate'].replace("-", "")
xml_time = jsonData['IssueTime'].replace(":", "")
filename = jsonData['AccountingSupplierParty']['Party']['PartyTaxScheme']['CompanyID'] + "_" + \
xml_date + "T" + xml_time + "_" + str(jsonData['ID']) + ".xml"
# filename = jsonData['AccountingSupplierParty']['Party']['PartyIdentification']['ID'] + "_%s_%s.xml" % (
# str((now.strftime("%Y%m%d%H%M%S"))), jsonData['ID'])
content = "attachment; filename=%s" % (filename)
response['Content-Disposition'] = content
return response
return HttpResponse("Not found")
This is part of ZATCA E-invoice system and the project code is writen with python django.
UBL specifications that aren't met generally fall into two categories:
An Attribute is required but you are not providing it.
The order of the attributes inside the element is wrong.
To solve your problem, you should inspect each element of your XML against the UBL Schema specification and find required attributes that you're not providing or attributes out of order..
Go to this site that lists the UBL Specifications:
http://www.datypic.com/sc/ubl21/ss.html
In the search box at the top, enter the name of the element followed by the word "Type" (e.g.: Invoice --> search for InvoiceType
In the element specifications, find each attribute that its relationship starts with [1 .. this attribute is mandatory, make sure you provide a value for it.
Check the order of the attribute and make sure they are added in the correct order.
Doing that will ensure that all your elements are compliant to the UBL specifications.
There are many problems in : https://sandbox.zatca.gov.sa/
As the results in coding and sharing the invoice have many errors Zakat has been warned over and over again

Python ElementTree adding a child

I have an xml file which looks like this:
<keyboard>
</keyboard>
I want to make it look like this:
<keyboard>
<keybind key="W-c-a"><action name="Execute"><command>sudo shutdown now</command></action></keybind>
</keyboard>
I have a function to add this which has parameters that will change the key and the command. Is this possible to do? If yes, how can I do this?
(The function):
def add_keybinding(self, keys, whatToExec):
keybinding = "<keybind key=\"%s\"><action name=\"Execute\"><command>%s</command><action></keybind>" % (keys, whatToExec)
f = open("/etc/xdg/openbox/rc.xml", "a")
try:
# I want to append the keybinding variable to the <keyboard>
except IOError as e:
print(e)
From the doc, you can try the following:
def add_keybinding(keys, whatToExec, filename):
keybind = ET.Element('keybind')
keybind.set("key", keys)
action = ET.SubElement(keybind, 'action')
action.set("name", "Execute")
command = ET.SubElement(action, 'command')
command.text = whatToExec
tree = ET.parse(filename)
tree.getroot().append(keybind)
tree.write(filename)
Explanation:
Create the keybind tag using xml.etree.ElementTree.Element : keybind = ET.Element('keybind')
Set a property using set: keybind.set("key", keys)
Create the action tag as a sub element of keybind using
xml.etree.ElementTree.SubElement: action = ET.SubElement(keybind, 'action')
Set the property as at step 2: action.set("name", "Execute")
Create command tag: action.set("name", "Execute")
Set command tag content using .text: command.text = whatToExec
Read file using xml.etree.ElementTree.parse: tree = ET.parse(filename)
Append keybind tag to the doc root element using append*
Export new xml to file using write
Full example:
import xml.etree.ElementTree as ET
from xml.dom import minidom
def add_keybinding(keys, whatToExec, filename):
keybind = ET.Element('keybind')
keybind.set("key", keys)
action = ET.SubElement(keybind, 'action')
action.set("name", "Execute")
command = ET.SubElement(action, 'command')
command.text = whatToExec
tree = ET.parse(filename)
tree.getroot().append(keybind)
tree.write(filename)
return tree
def prettify(elem):
rough_string = ET.tostring(elem, 'utf-8')
return minidom.parseString(rough_string).toprettyxml(indent=" ")
filename = "test.xml"
for i in range(3):
tree = add_keybinding(str(i), "whatToExec " + str(i), filename)
print(prettify(tree.getroot()))
Output:
<?xml version="1.0" ?>
<keyboard>
<keybind key="0">
<action name="Execute">
<command>whatToExec 0</command>
</action>
</keybind>
<keybind key="1">
<action name="Execute">
<command>whatToExec 1</command>
</action>
</keybind>
<keybind key="2">
<action name="Execute">
<command>whatToExec 2</command>
</action>
</keybind>
</keyboard>

How can I parse a XML file to a dictionary in Python?

I 'am trying to parse a XML file using the Python library minidom (even tried xml.etree.ElementTree API).
My XML (resource.xml)
<?xml version='1.0'?>
<quota_result xmlns="https://some_url">
</quota_rule>
<quota_rule name='max_mem_per_user/5'>
<users>user1</users>
<limit resource='mem' limit='1550' value='921'/>
</quota_rule>
<quota_rule name='max_mem_per_user/6'>
<users>user2 /users>
<limit resource='mem' limit='2150' value='3'/>
</quota_rule>
</quota_result>
I would like to parse this file and store inside a dictionnary the information in the following form and be able to access it:
dict={user1=[resource,limit,value],user2=[resource,limit,value]}
So far I have only been able to do things like:
docXML = minidom.parse("resource.xml")
for node in docXML.getElementsByTagName('limit'):
print node.getAttribute('value')
You can use getElementsByTagName and getAttribute to trace the result:
dict_users = dict()
docXML = parse('mydata.xml')
users= docXML.getElementsByTagName("quota_rule")
for node in users:
user = 'None'
tag_user = node.getElementsByTagName("users") #check the length of the tag_user to see if tag <users> is exist or not
if len(tag_user) ==0:
print "tag <users> is not exist"
else:
user = tag_user[0]
resource = node.getElementsByTagName("limit")[0].getAttribute("resource")
limit = node.getElementsByTagName("limit")[0].getAttribute("limit")
value = node.getElementsByTagName("limit")[0].getAttribute("value")
dict_users[user.firstChild.data]=[resource, limit, value]
if user == 'None':
dict_users['None']=[resource, limit, value]
else:
dict_users[user.firstChild.data]=[resource, limit, value]
print(dict_users) # remove the <users>user1</users> in xml
Output:
tag <users> is not exist
{'None': [u'mem', u'1550', u'921'], u'user2': [u'mem', u'2150', u'3']}

checking for a node in XML (minidom) and insering if it doesn't exist

I have pretty simple XML. I need to check if 2 nodes exist: preferences and item, inside it. There can be multiple items.
<settings>
<preferences>
<item>sometext</item>
</preferences>
</settings>
Now, if exists, I need to check nodeValue. If needed nodeValue is not there, I need to add it.
So far I am reading the file and looking for node but I don't know how to add it if it's not there (and save the file):
def readSettings(xmlFile):
xmldoc = minidom.parse(xmlFile)
cNodes = xmldoc.childNodes
boo = 0
try:
nList = cNodes[0].getElementsByTagName("preferences")
eList = nList[0].getElementsByTagName("item")
for a in eList:
tempstr=a.childNodes[0].nodeValue
if tempstr == 'yes':
### it is there, we don't need to do anything
boo = 1
break
except:
boo = 0
return( boo )
So, if boo is 0, that means node <item> with Nodevalue "yes" (<item>yes</item>) was not found.
How do I write it to this existing XML?

Change value in specific child element

I have some issues with my script.
First of i wanna make sure that the correct name has been given by the user. For example if I were to write "Name" it should not match with anything in my xml. If i were to write "NameY" it should match with given name and not anything else(for example "NameX should not be matched). I tried using wordboundry but it did not help as I thought it would.
When I try want to change value in NameY the script changes for all the values(even for NameX). I believe this is because it can't seperate the "names"?
I am using argparse for this and the code is in another function.
args.name = "the name to look for"
args.dirname = "file location"
args.value "the value I want to change to"
wordboundry = re.compile(r'(<NAME>(%s\b)<\/NAME>)' % args.name)
getName = ("{0}ROOTS/{0}ROOT/{0}ELEM/{0}SPEC/[{0}NAME]")
getDigit = ("{0}ROOTS/{0}ROOT/{0}ELEM/{0}SPEC/{0}DP/{0}NVP/[{0}CHECK]/[{0}DIGIT]")
for fileName in glob.glob(args.dirname):
print fileName
with open(fileName,"r") as file:
my_files_content = file.read()
if args.name in my_files_content: #instead of using args.name i was trying to use if re.search(wordboundry, my_files_content):
print "Parameter exist in this file\n"
tree = tree = ElementTree.ElementTree()
tree.parse(fileName)
ElementTree.register_namespace("", "http://something.com")
namespace = "{http://something.com}"
for names in tree.findall(getName.format(namespace)):
mathcName = names.find('{http://something.com}NAME').text
if mathcName == **args.paramName**:
for digits in tree.findall(getDigit.format(namespace)):
digitNumber = digits.find('{http://something.com}DIGIT').text
convertToString = ' '.join([str(mystring) for mystring in args.value]) #Convert to string
digits.find('{http://something.com}DIGIT').text = convertToString #This allows the script to changes the digit in the xml file
tree.write("test.xml", encoding='utf-8', xml_declaration=True)
else: print"NO MATCHES\n"
else:
print "i am not here"
else:
"Parameter does not exist in this file\n"
My XML
<?xml version="1.0" encoding="utf-8"?>
<TOP xmlns="http://something.com">
<ROOTS>
<ROOT>
<ELEM>
<SPEC>
<NAME>NameX</NAME>
<DP>
<NVP>
<CHECK>NameX_1</CHECK>
<DIGIT>3</DIGIT>
</NVP>
<NVP>
<CHECK>NameX_2</CHECK>
<DIGIT>20</DIGIT>
</NVP>
</DP>
</SPEC>
<SPEC>
<NAME>NameY</NAME>
<DP>
<NVP>
<CHECK>NameY</CHECK>
<DIGIT>7</DIGIT>
</NVP>
</DP>
</SPEC>
</ELEM>
</ROOT>
</ROOTS>
</TOP>
Edit fixed the problem by changning "is not None" to "== args.paramName"

Categories