CopyPastor

Detecting plagiarism made easy.

Score: 1; Reported for: Exact paragraph match Open both answers

Possible Plagiarism

Plagiarized on 2021-07-23
by Mads Hansen

Original Post

Original - Posted on 2016-11-25
by kjhughes



            
Present in both answers; Present only in the new answer; Present only in the old answer;

Your XML elements are bound to the namespace `http://iptc.org/std/nar/2006-10-01/`, but your XPath is not using any namespace-prefixes, so `/newsItem/itemMeta` is asking for elements that are bound to no namespace.
You could address them by just the `local-name()`:
/*[local-name()='newsItem']/*[local-name()='itemMeta']
Otherwise, you need to register the namespace with a namespace prefix, or use a custom NamespaceContext to resolve the namespace from your chosen namespace-prefix:
xpath.setNamespaceContext(new NamespaceContext() { public String getNamespaceURI(String prefix) { switch (prefix) { case "i": return "http://iptc.org/std/nar/2006-10-01/"; // ... } });
and then use that namespace-prefix in your XPath:
/i:newsItem/i:itemMeta
Defining namespaces in XPath <sub><sup>(recommended)</sup></sub> -------------------
XPath itself doesn't have a way to bind a namespace prefix with a namespace. Such facilities are provided by the hosting library.
It is recommended that you use those facilities and define namespace prefixes that can then be used to qualify XML element and attribute names as necessary.
---
Here are some of the various mechanisms which XPath hosts provide for specifying namespace prefix bindings to namespace URIs.
<sup><sub>(OP's original XPath, `/IntuitResponse/QueryResponse/Bill/Id`, has been elided to `/IntuitResponse/QueryResponse`.)</sub></sup>

**C#:**
<!-- language: lang-cs -->
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); nsmgr.AddNamespace("i", "http://schema.intuit.com/finance/v3"); XmlNodeList nodes = el.SelectNodes(@"/i:IntuitResponse/i:QueryResponse", nsmgr);
**Java (SAX):**
<!-- language: lang-java -->
NamespaceSupport support = new NamespaceSupport(); support.pushContext(); support.declarePrefix("i", "http://schema.intuit.com/finance/v3");
**Java (XPath):**
<!-- language: lang-java -->
xpath.setNamespaceContext(new NamespaceContext() { public String getNamespaceURI(String prefix) { switch (prefix) { case "i": return "http://schema.intuit.com/finance/v3"; // ... } });
- Remember to call [`DocumentBuilderFactory.setNamespaceAware(true)`](http://docs.oracle.com/javase/6/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#setNamespaceAware%28boolean%29). - See also: https://stackoverflow.com/questions/10720452/java-xpath-queries-with-default-namespace-xmlns
**JavaScript:**
See [Implementing a User Defined Namespace Resolver][1]:
<!-- language: lang-js -->
function nsResolver(prefix) { var ns = { 'i' : 'http://schema.intuit.com/finance/v3' }; return ns[prefix] || null; } document.evaluate( '/i:IntuitResponse/i:QueryResponse', document, nsResolver, XPathResult.ANY_TYPE, null );
**Perl ([LibXML][2]):**
<!-- language: lang-perl -->
my $xc = XML::LibXML::XPathContext->new($doc); $xc->registerNs('i', 'http://schema.intuit.com/finance/v3'); my @nodes = $xc->findnodes('/i:IntuitResponse/i:QueryResponse');
**Python ([lxml][3]):**
<!-- language: lang-python -->
from lxml import etree f = StringIO('<IntuitResponse>...</IntuitResponse>') doc = etree.parse(f) r = doc.xpath('/i:IntuitResponse/i:QueryResponse', namespaces={'i':'http://schema.intuit.com/finance/v3'})
**Python ([ElementTree][4]):**
<!-- language: lang-python -->
namespaces = {'i': 'http://schema.intuit.com/finance/v3'} root.findall('/i:IntuitResponse/i:QueryResponse', namespaces)
**Python ([Scrapy][6]):**
<!-- language: lang-python -->
response.selector.register_namespace('i', 'http://schema.intuit.com/finance/v3') response.xpath('/i:IntuitResponse/i:QueryResponse').getall()
**PhP:**
Adapted from [@Tomalak's answer using DOMDocument][8]:
<!-- language: lang-php -->
$result = new DOMDocument(); $result->loadXML($xml); $xpath = new DOMXpath($result); $xpath->registerNamespace("i", "http://schema.intuit.com/finance/v3"); $result = $xpath->query("/i:IntuitResponse/i:QueryResponse");
See also [@IMSoP's canonical Q/A on PHP SimpleXML namespaces][9].
**Ruby (Nokogiri):**
<!-- language: ruby -->
puts doc.xpath('/i:IntuitResponse/i:QueryResponse', 'i' => "http://schema.intuit.com/finance/v3")
Note that Nokogiri supports removal of namespaces,
<!-- language: ruby -->
doc.remove_namespaces!
but see the below warnings discouraging the defeating of XML namespaces.
**VBA:**
<!-- language: lang-vba -->
xmlNS = "xmlns:i='http://schema.intuit.com/finance/v3'" doc.setProperty "SelectionNamespaces", xmlNS Set queryResponseElement =doc.SelectSingleNode("/i:IntuitResponse/i:QueryResponse")

**VB.NET:**
<!-- language: lang-vb.net -->
xmlDoc = New XmlDocument() xmlDoc.Load("file.xml") nsmgr = New XmlNamespaceManager(New XmlNameTable()) nsmgr.AddNamespace("i", "http://schema.intuit.com/finance/v3"); nodes = xmlDoc.DocumentElement.SelectNodes("/i:IntuitResponse/i:QueryResponse", nsmgr) **SoapUI ([doc][5]):**
declare namespace i='http://schema.intuit.com/finance/v3'; /i:IntuitResponse/i:QueryResponse
**xmlstarlet:**
<!-- language: lang-sh -->
-N i="http://schema.intuit.com/finance/v3"
**XSLT:**
<!-- language: lang-xml -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:i="http://schema.intuit.com/finance/v3"> ...
Note that if the default namespace has an associated namespace prefix defined, using the `nsResolver()` returned by [`Document.createNSResolver()`][7] can obviate the need for a customer `nsResolver()`.
---
Once you've declared a namespace prefix, your XPath can be written to use it:
/i:IntuitResponse/i:QueryResponse
---
Defeating namespaces in XPath <sub><sup>(not recommended)</sup></sub> -------------------- An alternative is to write predicates that test against `local-name()`:
/*[local-name()='IntuitResponse']/*[local-name()='QueryResponse']
Or, in XPath 2.0:
/*:IntuitResponse/*:QueryResponse

Skirting namespaces in this manner works but is not recommended because it
- Under-specifies the full element/attribute name. - Fails to differentiate between element/attribute names in different namespaces (the very purpose of namespaces). Note that this concern could be addressed by adding an additional predicate to check the namespace URI explicitly<sup>1</sup>:
/*[ namespace-uri()='http://schema.intuit.com/finance/v3' and local-name()='IntuitResponse'] /*[ namespace-uri()='http://schema.intuit.com/finance/v3' and local-name()='QueryResponse']
<sup>1</sup>Thanks to [Daniel Haley][10] for the `namespace-uri()` note.
- Is excessively verbose.

[1]: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#Implementing_a_User_Defined_Namespace_Resolver [2]: http://search.cpan.org/dist/XML-LibXML/lib/XML/LibXML/XPathContext.pod [3]: http://lxml.de/xpathxslt.html#namespaces-and-prefixes [4]: https://stackoverflow.com/q/14853243/290085 [5]: https://www.soapui.org/docs/functional-testing/validating-messages/validating-xml-messages/ [6]: http://doc.scrapy.org/en/latest/index.html [7]: https://developer.mozilla.org/en-US/docs/Web/API/Document/createNSResolver [8]: https://stackoverflow.com/a/6475568/290085 [9]: https://stackoverflow.com/q/44894426/290085 [10]: https://stackoverflow.com/users/317052/daniel-haley

        
Present in both answers; Present only in the new answer; Present only in the old answer;