create xml snippet using dataweave (i.e. remove root element) - mule

desiring an output like this
</b>
<c>
<value1 />
</c>
<c>
<value2 />
</c>
<c>
<value3/>
</c>
instead of this
<a>
</b>
<c>
<value1 />
</c>
<c>
<value2 />
</c>
<c>
<value3/>
</c>
</a>
via dataweave. i understand the output wont necessarily be completely valid xml
any help appreciated thanks

Because it is going to miss a single root element it is not going to be valid XML. So DataWeave is not going to be able to read or write it directly. You can generate an XML for each element and concatenate them as a string to avoid having an XML parsing error.
The input is not valid, I fixed it as this:
<a>
<b/>
<c>
<value1 />
</c>
<c>
<value2 />
</c>
<c>
<value3/>
</c>
</a>
Script:
%dw 2.0
output application/java
---
(payload[0] pluck (value,key,index) -> {(key):value} )
reduce ((item, acc="") -> acc ++ write(item, "application/xml", {"writeDeclaration":false}) ++ "\n" )
Output:
<b/>
<c>
<value1/>
</c>
<c>
<value2/>
</c>
<c>
<value3/>
</c>
Note that I added a newline at the end of each string ("\n") for clarity. You can remove it if you want.

Related

Finding all HTML elements with attribute names that starts with 'aria'

Using XPath in Selenium or BeautifulSoup in Python, how can one get the tag-names (here 'a', 'button') and the values of 'aria' attributes (here Home, True, False) by knowing that those attributes start with 'aria'
<a aria-label="Home" id="1" />
<button aria-hidden="True" id="2" />
<button aria-pressed="False" id="2" />
Currently, I have to put in all attributes one-by-one, like this
driver.find_elements_by_xpath("//*[#aria-label]")
driver.find_elements_by_xpath("//*[#aria-pressed]")
What I need is something like (which, here, isn't correct),
driver.find_elements_by_xpath("//*#[starts-with('aria')]")

Transform XML with default values in Mulesoft

Assuming I have XMLs like
<a>
<b>Some Value</b>
</a>
...or...
<a>
<b type=1 />
</a>
...or...
<a/>
and want to have some values and attributes defined in output like
<a>
<b type=0>Some Value</b>
</a>
...or...
<a>
<b type=1>Empty</b>
</a>
...or...
<a>
<b type=0>Empty</b>
</a>
what would be best way to do so in Mulesoft?
Using script with lines like
if (payload.a == null ) payload.a={}
if (payload['a']['b']) payload['a']['b']={}
if (payload.a.b.type == null) payload.a.b.type=0;
or dataweave
%dw 1.0
%output application/xml
---
{
a: payload.a default { {b:{ b#type=0 }} }
}
I'm confused about syntax here.
If I understand correctly what you're asking, the following seems to work:
input:
<?xml version='1.0' encoding='UTF-8'?>
<root>
<a>
<b>Some Value</b>
</a>
<a>
<b type="1" />
</a>
<a/>
</root>
Dataweave:
%dw 1.0
%output application/xml
---
root: payload.root.*a mapObject (
a: {
b #(type: $.b.#type default "0"):
$.b when $.b != null and $.b != "" otherwise "Empty"
}
)
output:
<?xml version='1.0' encoding='UTF-8'?>
<root>
<a>
<b type="0">Some Value</b>
</a>
<a>
<b type="1">Empty</b>
</a>
<a>
<b type="0">Empty</b>
</a>
</root>

Python etree lxml moving a child from parent

I have xml of the form:
<b>
<a>
<c>some stuff</c>
<d> some more stuff</d>
</a>
</b>
which I want to reformat as:
<b>
<c>some stuff</c>
<a>
<d> some more stuff</d>
</a>
</b>
any ideas on how to do this using Python lxml?
So I finally solved it using dummy tags and the addnext argument:
def new_a(xml):
node_b=xml.xpath('/b')[0]
node_d=xml.xpath('/b/a/d')
node_d[0].addnext(etree.Element('dummy_tag'))
node_dummy=xml.xpath('/b/a/dummy_tag')
node_dummy[0].append(node_d[0])
etree.strip_tags(node_b,'a')
dummies=node_b.findall('dummy_tag')
for node in dummies:
node.tag='a'
return xml
So if:
xml_ini="<b><a><c>some stuff</c><d>some other stuff</d><e>even more stuff</e></a></b>"
xml=etree.fromstring(xml_ini)
xml_new=new_a(xml)
Then we go from this:
<b>
<a>
<c>some stuff</c>
<d>some other stuff</d>
<e>even more stuff</e>
</a>
</b>
To this:
<b>
<c>some stuff</c>
<a>
<d>some other stuff</d>
</a>
<e>even more stuff</e>
</b>

Understanding WebElement.findElement() and XPATH

I want to use the WebElement.findElement() API to locate a node inside the parent node using XPATH //span[#class='child-class']. I thought this would return me the <div> that is inside the parent. However, it is returning me the first one it found in the entire DOM tree. Did I use the wrong XPATH?
I have also tried using .//span[#class='child-class'] as the XPATH, but that does return anything.
Thank you.
UPDATE:
given the HTML below, I want to define a locator for the child-title <span> and child-date <span> and locate them using WebElement.findElement() API regardless of the parent being "//a/li[1]" or "//a/li[2]"
<a>
<li> parent 1
<div>
<span class="child-title child-style">title 1</span>
<span class="child-date child-style"> date 1</span>
<span class="child-author">author 1</span>
</div>
</li>
</a>
<a>
<li> parent 2
<div>
<span class="child-title child-style">title 2</span>
<span class="child-date child-style"> date 2</span>
<span class="child-author">author 3</span>
</div>
</li>
</a>
<a>
<li> parent 3
<div>
<span class="child-title child-style">title 3</span>
<span class="child-date child-style"> date 3</span>
<span class="child-author">author 3</span>
</div>
</li>
</a>
I have a WebElement parent2 initialized and located using "//a/li[2]",
WebElement child = parent2.findElement(By.xpath("//span[#class='child-author']")); would give me "author 1"
WebElement child = parent2.findElement(By.xpath("span[#class='child-author']")); would give me NoSuchElementException
There are my 2 comments with your sample code
1 - With your posted HTML, the xpath //a/li[2] is not found (we only have 3 elements with //a/li[1])
2 - Assume that we do have right code, you need to understand the differences between single slash and double slash in Xpath
a/b (single slash): select element that has "tag b" and "stands right after" an element that has "a tag"
E.g.:
<a>
<b>
<d>
<c>
</c>
</d>
</b>
</a>
AND
a//b (double slash): select element that has "tag b" and is n-level-child an element that has "a tag"
E.g.:
<a>
<c>
<d>
<b>
</b>
</d>
</c>
</a>
So, with your code
<a>
<li> parent 1
<div>
<span class="child-title child-style">title 1</span>
<span class="child-date child-style"> date 1</span>
<span class="child-author">author 1</span>
</div>
</li>
</a>
If you want to get Date Info, you should use
WebElement parent = driver.findElement(By.xpath("//a/li"));
WebElement date = parent.findElement(By.xpath("div/span[contains(#class, 'child-date')]"));
WebElement date = parent.findElement(By.xpath("//span[contains(#class, 'child-date')]"));
The code
WebElement date = parent.findElement(By.xpath("span[contains(#class, 'child-date')]"));
Will bring out NoSuchElementException because there is no [span] tag right after [li] tag
Hope help
Try something like:
Use dot(.) before double slash(//)
It looks for child under the given parent element.
Completely new question ... completely new answer. :(
Try something like:
WebElement parent1 = driver.findElement(By.xpath("//a[1]/li")); // use a[2] for parent2
WebElement author = parent1.findElement(By.xpath("span[#class='child-author']"));
WebElement date = parent1.findElement(By.xpath("span[contains(#class, 'child-date')]"));
WebElement title = parent1.findElement(By.xpath("span[contains(#class, 'child-title')]"));
Try something like :
//a/li[contains(text(), 'parent 1')]/div
It requests for "the <div> inside a <li> whose text contains 'parent 1' and who is inside a <a>.
It might not work if you have more parents because it works with a contains() (this xpath would also select <li> parent 10 ... </li>). It would be better if "parent x" were an attribute of the <li> instead of its text.

How to get first field witout any child value in xslt 1.0?

Do you know how to get only "ADH6170" in xslt 1.0
Thanks.
<h2>
ADH6170
<strong>
Bayan kol saati
</strong>
</h2>
<xsl:template match="h2">
<xsl:value-of select="//text()" />
</xsl:template>