XML return 所有节点名称都包含一个子字符串
XML return all node name contain a substring
由于我是 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 数据和 return 仅查询名称中包含字符串 "revenue" 的节点。所以输出应该是这样的:
<revenue>
<revenue>123</revenue>
<interestRevenue>234</interestRevenue>
<transactionRevenue>345</transactionRevenue>
<revenueOtherServices>109</revenueOtherServices>
</revenue>
其实我并没有使用编程语言。我有一个 XML 数据库在 eXist 上本地运行,它包含一个内置的 XQuery 引擎。因此,我正在寻找 XPath/XQuery 代码。
提前致谢!
您可以使用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>
这为您的示例提供了所需的输出。
XQuery 解决方案可能如下所示。 Return 一个最外层的元素 revenue
,并查找名称包含 "revenue" 的所有元素,无论是小写还是大写,这就是 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>
Actually I am not using a programming language.
嗯,您知道,XQuery 是 一种编程语言。在我看来,就是。
由于我是 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 数据和 return 仅查询名称中包含字符串 "revenue" 的节点。所以输出应该是这样的:
<revenue>
<revenue>123</revenue>
<interestRevenue>234</interestRevenue>
<transactionRevenue>345</transactionRevenue>
<revenueOtherServices>109</revenueOtherServices>
</revenue>
其实我并没有使用编程语言。我有一个 XML 数据库在 eXist 上本地运行,它包含一个内置的 XQuery 引擎。因此,我正在寻找 XPath/XQuery 代码。
提前致谢!
您可以使用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>
这为您的示例提供了所需的输出。
XQuery 解决方案可能如下所示。 Return 一个最外层的元素 revenue
,并查找名称包含 "revenue" 的所有元素,无论是小写还是大写,这就是 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>
Actually I am not using a programming language.
嗯,您知道,XQuery 是 一种编程语言。在我看来,就是。