考虑我有以下示例XML文件:
<ns1:create xmlns:ns1='http://predic8.com/wsdl/material/ArticleService/1/'>
<article xmlns:ns1='http://predic8.com/material/1/'>
<name xmlns:ns1='http://predic8.com/material/1/'>foo</name>
<description xmlns:ns1='http://predic8.com/material/1/'>bar</description>
<price xmlns:ns1='http://predic8.com/common/1/'>
<amount xmlns:ns1='http://predic8.com/common/1/'>00.00</amount>
<currency xmlns:ns1='http://predic8.com/common/1/'>USD</currency>
</price>
<id xmlns:ns1='http://predic8.com/material/1/'>1</id>
</article>
</ns1:create>
将其扁平化为一组xpath表达式的最佳(最有效)方法是什么。另请注意:我想忽略任何名称空间和属性信息。(如果需要,也可以将其作为预处理步骤来完成)。
所以我想作为输出:
/create/article/name
/create/article/description
/create/article/price/amount
/create/article/price/currency
/create/article/id
我正在用Java实现。
编辑: PS,在文本节点上没有数据的情况下,我也可能需要此方法,因此,例如,以下代码应生成与上述相同的输出:
<ns1:create xmlns:ns1='http://predic8.com/wsdl/material/ArticleService/1/'>
<article xmlns:ns1='http://predic8.com/material/1/'>
<name />
<description />
<price xmlns:ns1='http://predic8.com/common/1/'>
<amount />
<currency xmlns:ns1='http://predic8.com/common/1/'></currency>
</price>
<id xmlns:ns1='http://predic8.com/material/1/'></id>
</article>
</ns1:create>
您可以使用XSLT轻松完成此操作。查看示例,似乎只需要包含文本的元素的XPath。如果不是这种情况,请告诉我,我可以更新XSLT。
我创建了一个新的输入示例,以显示其如何处理同名兄弟姐妹。在这种情况下,<article>
。
XML输入
<ns1:create xmlns:ns1='http://predic8.com/wsdl/material/ArticleService/1/'>
<article xmlns:ns1='http://predic8.com/material/1/'>
<name xmlns:ns1='http://predic8.com/material/1/'>foo</name>
<description xmlns:ns1='http://predic8.com/material/1/'>bar</description>
<price xmlns:ns1='http://predic8.com/common/1/'>
<amount xmlns:ns1='http://predic8.com/common/1/'>00.00</amount>
<currency xmlns:ns1='http://predic8.com/common/1/'>USD</currency>
</price>
<id xmlns:ns1='http://predic8.com/material/1/'>1</id>
</article>
<article xmlns:ns1='http://predic8.com/material/2/'>
<name xmlns:ns1='http://predic8.com/material/2/'>some name</name>
<description xmlns:ns1='http://predic8.com/material/2/'>some description</description>
<price xmlns:ns1='http://predic8.com/common/2/'>
<amount xmlns:ns1='http://predic8.com/common/2/'>00.01</amount>
<currency xmlns:ns1='http://predic8.com/common/2/'>USD</currency>
</price>
<id xmlns:ns1='http://predic8.com/material/2/'>2</id>
</article>
</ns1:create>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="text()"/>
<xsl:template match="*[text()]">
<xsl:call-template name="genPath"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:template>
<xsl:template name="genPath">
<xsl:param name="prevPath"/>
<xsl:variable name="currPath" select="concat('/',local-name(),'[',
count(preceding-sibling::*[name() = name(current())])+1,']',$prevPath)"/>
<xsl:for-each select="parent::*">
<xsl:call-template name="genPath">
<xsl:with-param name="prevPath" select="$currPath"/>
</xsl:call-template>
</xsl:for-each>
<xsl:if test="not(parent::*)">
<xsl:value-of select="$currPath"/>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出量
/create[1]/article[1]/name[1]
/create[1]/article[1]/description[1]
/create[1]/article[1]/price[1]/amount[1]
/create[1]/article[1]/price[1]/currency[1]
/create[1]/article[1]/id[1]
/create[1]/article[2]/name[1]
/create[1]/article[2]/description[1]
/create[1]/article[2]/price[1]/amount[1]
/create[1]/article[2]/price[1]/currency[1]
/create[1]/article[2]/id[1]
更新
为了使XSLT适用于所有元素,只需[text()]
从中删除谓词match="*[text()]"
。这将输出每个元素的路径。如果您不希望包含其他元素(例如create,article和price)的元素的路径输出,请添加谓词[not(*)]
。这是一个更新的示例:
新的XML输入
<ns1:create xmlns:ns1='http://predic8.com/wsdl/material/ArticleService/1/'>
<article xmlns:ns1='http://predic8.com/material/1/'>
<name />
<description />
<price xmlns:ns1='http://predic8.com/common/1/'>
<amount />
<currency xmlns:ns1='http://predic8.com/common/1/'></currency>
</price>
<id xmlns:ns1='http://predic8.com/material/1/'></id>
</article>
<article xmlns:ns1='http://predic8.com/material/2/'>
<name xmlns:ns1='http://predic8.com/material/2/'>some name</name>
<description xmlns:ns1='http://predic8.com/material/2/'>some description</description>
<price xmlns:ns1='http://predic8.com/common/2/'>
<amount xmlns:ns1='http://predic8.com/common/2/'>00.01</amount>
<currency xmlns:ns1='http://predic8.com/common/2/'>USD</currency>
</price>
<id xmlns:ns1='http://predic8.com/material/2/'>2</id>
</article>
</ns1:create>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="text()"/>
<xsl:template match="*[not(*)]">
<xsl:call-template name="genPath"/>
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template name="genPath">
<xsl:param name="prevPath"/>
<xsl:variable name="currPath" select="concat('/',local-name(),'[',
count(preceding-sibling::*[name() = name(current())])+1,']',$prevPath)"/>
<xsl:for-each select="parent::*">
<xsl:call-template name="genPath">
<xsl:with-param name="prevPath" select="$currPath"/>
</xsl:call-template>
</xsl:for-each>
<xsl:if test="not(parent::*)">
<xsl:value-of select="$currPath"/>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出量
/create[1]/article[1]/name[1]
/create[1]/article[1]/description[1]
/create[1]/article[1]/price[1]/amount[1]
/create[1]/article[1]/price[1]/currency[1]
/create[1]/article[1]/id[1]
/create[1]/article[2]/name[1]
/create[1]/article[2]/description[1]
/create[1]/article[2]/price[1]/amount[1]
/create[1]/article[2]/price[1]/currency[1]
/create[1]/article[2]/id[1]
如果删除[not(*)]
谓词,则输出将是这样(每个元素都会输出一个路径):
/create[1]
/create[1]/article[1]
/create[1]/article[1]/name[1]
/create[1]/article[1]/description[1]
/create[1]/article[1]/price[1]
/create[1]/article[1]/price[1]/amount[1]
/create[1]/article[1]/price[1]/currency[1]
/create[1]/article[1]/id[1]
/create[1]/article[2]
/create[1]/article[2]/name[1]
/create[1]/article[2]/description[1]
/create[1]/article[2]/price[1]
/create[1]/article[2]/price[1]/amount[1]
/create[1]/article[2]/price[1]/currency[1]
/create[1]/article[2]/id[1]
这是XSLT的另一个版本,速度提高了约65%:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="text()"/>
<xsl:template match="*[not(*)]">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="concat('/',local-name(),'[',count(preceding-sibling::*[local-name()=local-name(current())])+1,']')"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="node()"/>
</xsl:template>
</xsl:stylesheet>
问题内容: 给定一组XPath映射,我希望能够生成一个完整的XML文件。 输入可以在两个映射中指定:(1)列出XPath表达式和值的映射;(2)另一个定义了适当的名称空间。 对于命名空间: 还要注意,同样重要的是,我还必须处理XPath Attributes 表达式。例如:我也应该能够处理属性,例如: 最终输出应如下所示: PS:这是对先前提出的问题的更详细的问题,尽管由于一系列进一步的要求和说明
在我的工作中,我通过将AVRO文件复制到HDFS中,然后在impala中执行“refresh”,将这些文件导入impala表。 但是当我想用压缩文件做的时候,它没有起作用。 hive>设置avro.output.codec=bzip2; 创建表: 创建表(bigint COMMENT“from deserializer”、string COMMENT“from deserializer”、stri
问题内容: 从XPath表达式的映射填充(或生成)XML模板文件的最佳方法是什么? 要求是我们需要从模板开始(因为它可能包含XPath表达式中未捕获的信息)。 例如,起始模板可能是: 然后提供给我们,类似于: 然后,我们应该生成: 我是用Java实现的,尽管如果可能的话,我会首选基于XSLT的解决方案。 问题答案: 此转换从“表达式”创建具有所需结果结构的XML文档-仍需将其转换为最终结果: 当此
问题内容: 我是JAXB的新手,并且想知道是否有一种方法可以使用xpath表达式将XML解组到我的响应对象。问题是我正在呼叫第三方Web服务,收到的响应有很多详细信息。我不希望将XML中的所有详细信息映射到我的响应对象。我只希望从xml映射一些细节,使用这些细节我可以使用特定的XPath表达式并将其映射到我的响应对象。有没有注释可以帮助我实现这一目标? 例如考虑以下响应 我只对检索街道名称感兴趣,
我是JAXB新手,想知道是否有一种方法可以使用xpath表达式将XML解组到响应对象。问题是我正在呼叫第三方Web服务,我收到的回复有很多详细信息。我不希望将XML中的所有细节映射到我的响应对象。我只希望映射xml中的一些细节,使用特定的XPath表达式可以获得这些细节,并将其映射到响应对象。有没有注释可以帮助我实现这一点? 例如,考虑以下响应 我只对检索街道名称感兴趣,所以我想使用xpath表达
我正在使用Julia的ZipFile包来提取和处理csv文件。没问题,但是当我遇到zip文件中的zip文件时,我也想处理它,但是遇到了一个错误。 Julia ZipFile文档如下:https://zipfilejl.readthedocs.io/en/latest/ 对如何做到这一点有什么想法吗?