您可以使用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>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)