Reputation: 51
I am trying to get all values of a certain XML element. However, the namespace is not defined. I've tried using the local-name() function but am not having any luck.
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xml:base="https://www.website.com" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<id>A</id>
<title type="text"></title>
<updated>2015-07-21T02:40:30Z</updated>
<author>
<name />
</author>
<link rel="edit" title="Application" href="A(1347)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/b" type="application/atom+xml;type=feed" title="B" href="A(1347)/B" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/C" type="application/atom+xml;type=feed" title="C" href="A(1347)/C" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/D" type="application/atom+xml;type=entry" title="D" href="A(1347)/D" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/E" type="application/atom+xml;type=feed" title="E" href="A(1347)/E">
<m:inline>
<feed>
<title type="text">E</title>
<id>1347</id>
<updated>2015-07-21T02:40:30Z</updated>
<link rel="self" title="E" href="A(1347)/E" />
<entry>
<id>www.website.com/</id>
<title type="text"></title>
<updated>2015-07-21T02:40:30Z</updated>
<author>
<name />
</author>
<link rel="edit" title="E" href="E(4294)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/A" type="application/atom+xml;type=entry" title="Application" href="E(4294)/A" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/D" type="application/atom+xml;type=entry" title="D" href="E(4294)/D" />
<category term="APIModel.FileBaseDocuments" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:ID m:type="Edm.Int32">4294</d:ID>
<d:Type>123</d:Type>
</m:properties>
</content>
</entry>
<entry>
<id>www.website.com</id>
<title type="text"></title>
<updated>2015-07-21T02:40:30Z</updated>
<author>
<name />
</author>
<link rel="edit" title="E" href="E(4295)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/A" type="application/atom+xml;type=entry" title="A" href="E(4295)/A" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/D" type="application/atom+xml;type=entry" title="D" href="E(4295)/D" />
<category term="APIModel.FileBaseDocuments" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:ID m:type="Edm.Int32">4295</d:ID>
<d:Type>456</d:Type>
</m:properties>
</content>
</entry>
</feed>
</m:inline>
</link>
</entry>
I want to retrieve all values inside of "m:properties/d:ID m:type="Edm.Int32" (in this case 4294) but I am getting no luck. So for one file, there would be one "feed" tag filled with multiple "entry" tags. Inside these tags there would be one "m:properties/d:ID m:type="Edm.Int32" which I need to retrieve. Any suggestion on what the correct xPath would be for this situation?
Upvotes: 1
Views: 244
Reputation: 12729
Use the @exclude-result-prefixes
attribute to filter out the extraneous namespaces in your output. You don't need to declare the http://www.w3.org/2005/Atom in your transform, unless you need it for other purposes, but even so, it is probably a good thing.
Just match on expression m:properties/d:ID[@m:type='Edm.Int32']
to get your required data.
For example, this transform, when applied to your given input document ....
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns:atom="http://www.w3.org/2005/Atom"
version="2.0"
exclude-result-prefixes="xsl d m atom">
<xsl:output encoding="utf-8" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="/">
<Edm.Int32s>
<xsl:apply-templates />
</Edm.Int32s>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="text()" />
<xsl:template match="m:properties/d:ID[@m:type='Edm.Int32']">
<value><xsl:value-of select="text()" /></value>
</xsl:template>
</xsl:stylesheet>
... yields output ....
<edm.int32s>
<value>4294</value>
<value>4295</value>
</edm.int32s>
I have assumed from your question tags that you want an XSLT transform. If you just wanted a simple XPath expression to apply directly to the document, you could use ...
//m:properties/d:ID[@m:type='Edm.Int32']/text()
(passing, of course, the namespace declarations for m and d).
Upvotes: 0
Reputation: 107247
Instead of resorting to namespace agnostic xml by using local-name()
, why not register a namespace for the default namespace, e.g. x
prefix for xmlns:x="http://www.w3.org/2005/Atom"
, and then your Xpath would be something like:
//x:feed/x:entry/x:content/m:properties/d:ID[@m:type='Edm.Int32']
The local-name()
approach is more verbose:
//*[local-name()='feed']/*[local-name()='entry']/*[local-name()='content']
/*[local-name()='properties']/*[local-name()='ID' and @m:type='Edm.Int32']
Example of both approaches here
Upvotes: 1