xpath to pull nodes based on element partial match - xpath

On the below xml snip i'd like to pull row nodes for different batches which is essentially a time stamp, i.e., JP1800 stands for Japan 18 o'clock time.
//*[Batch='LN12000'] pulls all London noon nodes while
data/row pulls all of them including empty Batch values.
How would I pull all London times as //*[Batch='LN'*] does not work?
<?xml version="1.0"?>
-<data>
+<header>
+<row>
+<row>
+<row>
-<row>
<Date>2019-10-21</Date>
<Series>23</Series>
<OnTheRun>N</OnTheRun>
<Depth>0</Depth>
<Batch>JP1700</Batch>
</row>
-<row>
<Date>2019-10-21</Date>
<Series>23</Series>
<OnTheRun>N</OnTheRun>
<Depth>4</Depth>
<Batch>JP1800</Batch>
</row>

It sounds like you're looking for something like starts-with function. :
//header/row/Batch[starts-with(.,"LN")]
And here we have some PHP code exemple, look:
<?php
$xml = <<<XML
<?xml version="1.0"?>
<data>
<header>
<row>
<Date>2019-10-21</Date>
<Series>23</Series>
<OnTheRun>N</OnTheRun>
<Depth>0</Depth>
<Batch>JP1700</Batch>
</row>
<row>
<Date>2019-02-05</Date>
<Series>27</Series>
<OnTheRun>X</OnTheRun>
<Depth>89</Depth>
<Batch>LN9877</Batch>
</row>
</header>
</data>
XML;
$dom = new DOMDocument();
$dom->loadXML($xml);
$xpath = new DOMXPath($dom);
$query = $xpath->query('//header/row/Batch[starts-with(.,"LN")]');
/** #var DOMElement $node */
foreach ($query as $node) {
print($node->nodeValue); //outputs LN9877
}
https://www.w3.org/TR/1999/REC-xpath-19991116/#function-starts-with

Related

XPath: return first met child which has specific attribute

Have following hierarchy:
Parent1
--> child1(#name = 'abc')
--> child2(#name = 'xyz')
--> child3(#name = 'qqq')
Parent2
--> child1
--> child2(#name = 'yui')
XPath which returns following nodes needed:
child1 from Parent1
and
child2 from Parent2
the rule is following:
return first occurred child only which has specific attribute, in this case #name
note:
first() and [1] doesn't work
The following xpath:
/root/node()/node()[#name][position()=1]
With this XML:
<?xml version="1.0" encoding="utf-8"?>
<root>
<parent1>
<child1 name="abc"></child1>
<child2 name="xyz"></child2>
<child3 name="qqq"></child3>
</parent1>
<parent2>
<child1></child1>
<child2 name="yui"></child2>
</parent2>
</root>
Returns:
Element='<child1 name="abc" />'
Element='<child2 name="yui" />'

JAXB Moxy getValueByXpath gives null

I want to see if a theme element exists with specified name in the following xml file.
input.xml
<data>
<artifacts>
<document id="efqw4eads">
<name>composite</name>
</document>
<theme id="1">
<name>Terrace</name>
</theme>
<theme id="2">
<name>Garage</name>
</theme>
<theme id="3">
<name>Reception</name>
</theme>
<theme id="4">
<name>Grade II</name>
</theme>
</artifacts>
</data>
I have the following code. return true statement of the method is never executed. answer always contains a null value.
public boolean themeExists(String name, Data data){
String expression = "artifacts/theme[name='"+name+"']/name/text()";
String answer = jaxbContext.getValueByXPath(data, expression, null, String.class);
if(answer == null || answer.equals("")){
return false;
}
return true;
}
This use case isn't currently supported by EclipseLink JAXB (MOXy). I have opened the following enhancement you can use to track our progress:
http://bugs.eclipse.org/413823
There is no <artifacts/> element you're look for in the first axis step. Your XPath expression should be something like
String expression = "data/theme[name='"+name+"']/name/text()";

Returning List<string> from XDocument

<dataList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<headers>
<header>Template name</header>
</headers>
<rows>
<row>
<data>Template1</data>
</row>
<row>
<data>Template2</data>
</row>
</rows>
</dataList>
XDocument xml = new XDocument();
xml = XDocument.Parse(xmlstringFromAbove);
List<string> list = (from c in xml.Elements("data")
select c.Value).ToList();
This code returns an empty list.
How can I get a list of strings containing Template1 and Template2 ?
The Elements method only returns immediate children, use Descendants instead:
var xml = XDocument.Parse(xmlstringFromAbove);
var list = (from c in xml.Descendants("data") select c.Value).ToList();

Add comment nodes outside root with ruby-libxml

I am writing an xml exporter in ruby and I am using libxml package for it.
I want to write some comment nodes outside the root element
<?xml version="1.0" encoding="UTF-8"?>
<!-- comment -->
<root>
<childnode />
</root>
How do I accomplish export to above format?
Sample ruby code to generate the above (without accounting for comment node)
doc = XML::Document.new()
rootNode = XML::Node.new('root')
doc.root = rootNode
childNode = XML::Node.new('childnode')
childnode << rootNode
ended up editing the xml string manually to add the comments outside the root node (for both libxml and nokogiri
<?xml version="1.0" encoding="UTF-8" ?>
<List type = "" =”00:75:00” =”00:00:05”>
</List>
Yes
<?xml version="1.0" encoding="UTF-8" ?>
<List type = "update" >
</List>

YQL Losing HTML Element Attributes?

YQL Console Link
Query:
select * from html where url='http://www.cbs.com/shows/big_brother/video/' and xpath='//div[#id="cbs-video-metadata-wrapper"]/div[#class="cbs-video-share"]/a'
Returns:
<?xml version="1.0" encoding="UTF-8"?>
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
yahoo:count="1" yahoo:created="2011-07-09T23:14:02Z" yahoo:lang="en-US">
<diagnostics>
<publiclyCallable>true</publiclyCallable>
<url execution-time="146" proxy="DEFAULT"><![CDATA[http://www.cbs.com/shows/big_brother/video/]]></url>
<user-time>163</user-time>
<service-time>146</service-time>
<build-version>19262</build-version>
</diagnostics>
<results>
<a class="twitter-share-button" href="http://twitter.com/share"/>
</results>
</query>
Should Return Something Similar To:
<results>
</results>
If I back out the query one level, it totally strips out the element, which I could also use to get the data I need.
We have a new html parser that recognizes custom attributes now.
Add compat="html5" to trigger the new parser.
e.g.:
select * from html where url = "http://mydomain.com" and compat="html5"

Resources