Iterparse returns empty iterable when parsing xml with a default namespace - iterparse

I'm parsing an xml document using iterparse.
from lxml import etree
import tempfile
content = """<root xmlns="blah.com">
<foo>
<attribute id="3" />
</foo>
<foo>
<structure>
<baz>
<x>g</x>
</baz>
</structure>
</foo>
</root>"""
src_file = tempfile.NamedTemporaryFile()
src_file.write(content)
src_file.flush()
context = etree.iterparse(
src_file.name,
events=("end", ),
tag="foo",
)
for event, element in context:
print event
print element
Expected result: I see a few end events
Actual result: nothing happens
A few things I tried:
If I remove the namespace from the xml, it works fine.
If I use a namespace with a prefix like xlmns:t="blah.com" it also works fine.
Removing the tag="foo" also makes it work fine.
However I would like to use both a base tag, and a default namespace. Is this a bug with iterparse? Am I doing something else wrong?
Edit: edited the code to make it copy-pasteable without ident errors.

Ah the problems with parsers! Your tag must also reflect the complete path. Use your namespace in the tag like so: tag="{blah.com}foo".

Related

Replacing XML node key using dataprovider karate

I am reading my xml structure from a file and replacing the values from the examples
def inputXml = read('classpath:xml/input.xml')
My xml structure is like below
<input>
<data>
<props>
<p n="AMOUNT">1000</p>
<p n="NAME">name</p>
<p n="{ACCOUNTTYPE}">purpose</p>
</props>
</data>
</input>
I am driving data from examples and setting/replacing the input xml as below
* set inputXml/input/data/props/p[#n='AMOUNT'] = <AMOUNT> -- Works fine
* set inputXml/input/data/props/p[#n='NAME'] = <NAME> -- Works fine
Examples:
|AMOUNT|NAME|ACCOUNTTYPE|PURPOSE|
|100|abc|BUSINESS|smallbusiness|
|2000|def|PERSONAL|home|
I want to update the "n" tag name ACCOUNTTYPE and corresponsding PURPOSE similar to above(both key and value). Is there a way to achieve this in Karate? Please suggest.
Is is possible to use '#(accountType)' and '#(purpose)' inside the xml file similar to json and run?
Is is possible to use '#(accountType)' and '#(purpose)' inside the xml file
Yes. Please read the docs: https://github.com/intuit/karate#embedded-expressions
And the examples: xml.feature
Given def user = <user><name>john</name></user>
And def lang = 'en'
When def session = <session><locale>#(lang)</locale><sessionUser>#(user)</sessionUser></session>

Default namespace of the xsl:document

I created originally the following variable:
<xsl:variable as="document-node()" name="changesTexts">
<xsl:document>
<ps >
<p>Processed with <ptr target="#{$applicationID}"/>.</p>
<p>proofreading according to workflow 1.1.</p>
</ps>
</xsl:document>
</xsl:variable>
When I tried to access it like this
<xsl:variable name="p" select="$changesTexts//p"/>
It didn't work: an empty item() was the result.
After I added the namespace to the root element,
<ps xmlns="http://www.music-encoding.org/ns/mei">
I can access the desired elements by:
<xsl:variable name="p" select="$changesTexts//mei:p"/>
So basically I solved my problem but I would like to understand how the things work. I couldn't figure out what kind of default namespace the elements in the first case get. I tried:
name() (BTW this doesn't show me the namespace in the regular xml document either)
namespace-uri()
Also, I noticed in the debugger, that the variable $changesTexts is of the type document-node and in other cases, when I use fn:document(), the variables are of the type document-node(1). So there is obviously some subtle difference (?)
When you use a literal result element S in XSLT to create an element R in your result tree, the expanded name of R will be the same as the expanded name of S: that is, it will have the same local-name and the same namespace.
So the namespace of the elements constructed by your <ps> and <p> instructions is determined by the default namespace declared in the stylesheet (probably on the xsl:stylesheet element, but it could be on some inner element).

Edit XML tag by attribute

I have a XML document which looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<Data key="dailyKey">19283</Data>
</Configuration>
And in my vb.net program I want to change the value from "<Data>" by the attribute "dailyKey"
I have tried to understand myself on this but cannot figure out how to edit TAG by ATTRIBUTE
Please help, Richard
You could use XPath expressions and the SelectSingleNode method like this:
Dim node = xmlDoc.SelectSingleNode("//data[#key=""dailyKey""]")
Then you can modify the value of node as you wish to. You can find more XPath examples at MSDN.
The workflow in its entirety would be:
1. Load the XML Document for manipulation
You can use the XmlDocument class to load (and subsequently save) your XML Document like this:
Dim xmlDoc As New XmlDocument()
xmlDoc.Load("<Here goes your url // You can also feed in a stream to this method>")
2. Locate the node you want to modify
As mentioned earlier, use the SelectSingleNode function to locate the node you are trying to modify the value of. It takes an XPath expression.
Dim node = xmlDoc.SelectSingleNode("//data[#key=""dailyKey""]")
3. Modify the node
You can now edit the node (tag) in whatever way you wish. It seems you want to edit the contained value. Do it by changing the Value property of the XmlNode:
node.Value = 224062 'Random value. Change to suit your needs.
4. Save the XML Document (Obviously :P)
xmlDoc.Save()

How to set boolean in xml-action script

I am trying to set a flag so I do something like this:
<set field="existingFound" value="false" type="Boolean"/>
but the following line prints "true" in the log:
<log message="storeProperty, existingFound (0): ${existingFound}"/>
What is the best way to set flags?
The set.#value attribute is interpreted as a Groovy String (GString) so any non-empty value will be interpreted as true. The set.#from attribute is interpreted as a Groovy expression, so simply using from="false" instead of value="false" will get the desired result.
To see the generated Groovy code from an XML actions block you can write code that will cause an error and then the script will be logged, or you can change the log4j.xml file to turn on "debug" level logging for the XmlActions class (the latest log4j.xml file in the GitHub repository has an example of this). Looking at the Groovy code generated from the XML elements is a good way to track down issues when what is happening just doesn't make sense.

XML configuration of Zend_Form: child nodes and attributes not always equal?

A set of forms (using Zend_Form) that I have been working on were causing me some headaches trying to figure out what was wrong with my XML configuration, as I kept getting unexpected HTML output for a particular INPUT element. It was supposed to be getting a default value, but nothing appeared.
It appears that the following 2 pieces of XML are not equal when used to instantiate Zend_Form:
Snippet #1:
<form>
<elements>
<test type="hidden">
<options ignore="true" value="foo"/>
</test>
</elements>
</form>
Snippet #2:
<form>
<elements>
<test type="hidden">
<options ignore="true">
<value>foo</value>
</options>
</test>
</elements>
</form>
The type of the element doesn't appear to make a difference, so it doesn't appear to be related to hidden fields.
Is this expected or not?
As it was rather quiet on here, I took a look further into the source code and documentation.
On line 259 of Zend_Config_Xml, the SimpleXMLElement object attributes are converted to a string, resulting in:
options Object of: SimpleXMLElement
#attributes Array [2]
label (string:7) I can't see this because
value (string:21) something happens to this
becoming
options (string:21) something happens to this
So, I hunted through the documentation only to find that "value" is a reserved keyword when used as an attribute in an XML file that is loaded into Zend_Config_Xml:
Example #2 Using Tag Attributes in Zend_Config_Xml
"..Zend_Config_Xml also supports two
additional ways of defining nodes in
the configuration. Both make use of
attributes. Since the extends and the
value attributes are reserved keywords
(the latter one by the second way of
using attributes), they may not be
used..."
Thus, it would appear to be "expected" according to the documentation.
I'm not entirely happy that this is a good idea though, considering "value" is an attribute of form elements.
Don't worry about this. The reserved keywords were moved to their own namespace, and the previous attributes were depricated. In Zend Framework 2.0 the non-namespaced attributes will be removed so you can use them again.