由于我是XPath / XQuery的新手,并且尝试查询大量的xml文件数据,所以我想,也许有人可以帮我解决这个问题。
我有一个xml数据,如下所示:
<financial_statement>
<revenue>123</revenue>
<interestRevenue>234</interestRevenue>
<salaries>12<salaries>
<transactionRevenue>345</transactionRevenue>
<revenueOtherServices>109</revenueOtherServices>
<sales>783</sales>
<costs>746</costs>
.....
</financial_statement>
我想查询此xml数据并仅返回包含字符串&#34; revenue&#34;在他们的名字。所以输出应该如下:
<revenue>
<revenue>123</revenue>
<interestRevenue>234</interestRevenue>
<transactionRevenue>345</transactionRevenue>
<revenueOtherServices>109</revenueOtherServices>
</revenue>
其实我没有使用编程语言。我有一个在eXist本地运行的XML数据库,它包含一个内置的XQuery引擎。因此,我正在寻找XPath / XQuery代码。
提前致谢!
答案 0 :(得分:1)
XQuery解决方案可能如下所示。返回最外面的元素revenue
,并查找名称中包含&#34; revenue&#34;(小写或大写)的所有元素,它们是translate()
函数的作用。
这里,输入文档被分配给变量$x
,但您也可以使用doc()
函数或任何其他方法来检索由eXist提供的XML数据。
<强>的XQuery 强>
let $x := <financial_statement><revenue>123</revenue><interestRevenue>234</interestRevenue><salaries>12</salaries><transactionRevenue>345</transactionRevenue><revenueOtherServices>109</revenueOtherServices><sales>783</sales><costs>746</costs></financial_statement>
return <revenue>{$x//*[contains(translate(name(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'revenue')]}</revenue>
使用translate()
可保证XPath 1.0的可移植性,但由于XQuery使用XPath 2.0,您还可以使用lower-case()
或upper-case()
来模仿不区分大小写的contains()
函数。
XML输出
<revenue>
<revenue>123</revenue>
<interestRevenue>234</interestRevenue>
<transactionRevenue>345</transactionRevenue>
<revenueOtherServices>109</revenueOtherServices>
</revenue>
如果您真的要求XSLT解决方案,以下转换可以满足您的需求。由于XQuery和XSLT都使用XPath,因此方法几乎相同。
XML输入
<financial_statement>
<revenue>123</revenue>
<interestRevenue>234</interestRevenue>
<salaries>12</salaries>
<transactionRevenue>345</transactionRevenue>
<revenueOtherServices>109</revenueOtherServices>
<sales>783</sales>
<costs>746</costs>
</financial_statement>
XSLT样式表
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<revenue>
<xsl:apply-templates/>
</revenue>
</xsl:template>
<xsl:template match="*[contains(translate(name(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'revenue')]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:transform>
XML输出
<revenue>
<revenue>123</revenue>
<interestRevenue>234</interestRevenue>
<transactionRevenue>345</transactionRevenue>
<revenueOtherServices>109</revenueOtherServices>
</revenue>
其实我没有使用编程语言。
嗯,你知道,XQuery 是一种编程语言。在我看来,就是这样。
答案 1 :(得分:-1)
您可以使用name
功能。这是一个XSLT 1.0解决方案。
<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8"/>
<xsl:template match="*">
<xsl:variable name="n" select="name (.)"/>
<xsl:element name="{$n}">
<xsl:for-each select="@*">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="/">
<xsl:element name="revenue">
<xsl:apply-templates select="financial_statement"/>
</xsl:element>
</xsl:template>
<xsl:template match="financial_statement">
<xsl:for-each select="*">
<xsl:variable name="n" select="name (.)"/>
<xsl:if test="contains ($n, "revenue") or contains ($n, "Revenue")">
<xsl:apply-templates select="."/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这为您的示例提供了所需的输出。