如何将XML文件压缩为一组xpath表达式?

如何将XML文件压缩为一组xpath表达式?,第1张

如何将XML文件压缩为一组xpath表达式?

您可以使用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>&#xA;</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>&#xA;</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>&#xA;</xsl:text>        <xsl:apply-templates select="node()"/>    </xsl:template></xsl:stylesheet>


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5498555.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存