提取所有节点的 Xpath,然后提取它们的属性 [英] Extract Xpaths of all nodes and then their attributes

查看:26
本文介绍了提取所有节点的 Xpath,然后提取它们的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我的入门状态,我在过去 2 天一直在使用 xslt.我的要求是,给定任何输入 XML 文件,我希望输出是所有标签的所有 XPath 的列表,按顺序排列它们出现在原始 XML 文档中(父级,然后是父级,父级属性列表/子级、父级/子级/childOFchild 等).XSLT 不应特定于任何单个 XML 模式.它应该适用于任何有效的 XML 文件.

I am struggling with xslt from the past 2 days, owing to my starter status.My requirement is that given any input XML file ,I want the output to be a list of all the XPaths of all the tags in order in which they appear in the original XML document(parent, then parent,parents Attributes list/child, parent/child/childOFchild and so forth). THe XSLT should not be specific to any single XMl schema. It should work for any XML file, which is a valid one.

例如:

如果输入 XML 是:

If the Input XML Is :

<v1:Root>
<v1:UserID>test</v1:UserID>
<v1:Destination>test</v1:Destination>
<v1:entity name="entiTyName">
<v11:attribute name="entiTyName"/>
<v11:attribute name="entiTyName"/>
<v11:attribute name="entiTyName"/>
<v11:filter type="entiTyName">
<v11:condition attribute="entiTyName" operator="eq" value="{FB8D669E-D090-E011-8F43-0050568E222C}"/>
<v11:condition attribute="entiTyName" operator="eq" value="1"/>
</v11:filter>
<v11:filter type="or">
<v11:filter type="or">
<v11:filter type="and">
<v11:filter type="and">
<v11:condition attribute="cir_customerissuecode" operator="not-like" value="03%"/>
</v11:filter>
</v11:filter>
</v11:filter>
</v11:filter>
</v1:entity>
</v1:Root>

我希望我的输出是:

/v1:Root/v1:UserID
/v1:Root/v1:Destination
/v1:Root/v1:entity/@name
/v1:Root/v1:entity/v11:attribute
/v1:Root/v1:entity/v11:attribute/@name
/v1:Root/v1:entity/v11:attribute[2]
/v1:Root/v1:entity/v11:attribute[2]/@name
/v1:Root/v1:entity/v11:attribute[3]
/v1:Root/v1:entity/v11:attribute[3]/@name
/v1:Root/v1:entity/v11:filter/@type
/v1:Root/v1:entity/v11:filter/v11:condition
/v1:Root/v1:entity/v11:filter/v11:condition/@attribute
/v1:Root/v1:entity/v11:filter/v11:condition/@operator
/v1:Root/v1:entity/v11:filter/v11:condition/@value
/v1:Root/v1:entity/v11:filter/v11:condition[2]
/v1:Root/v1:entity/v11:filter/v11:condition[2]/@attribute
/v1:Root/v1:entity/v11:filter/v11:condition[2]/@operator
/v1:Root/v1:entity/v11:filter/v11:condition[2]/@value
/v1:Root/v1:entity/v11:filter[2]/v11:filter/@type
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/@type
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter/@type
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter/v11:condition
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter/v11:condition/@attribute
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter/v11:condition/@operator
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter/v11:condition/@value
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/@type
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/v11:condition
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/v11:condition/@attribute
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/v11:condition/@operator
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/v11:condition/@value
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/v11:condition[2]
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/v11:condition[2]/@attribute
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/v11:condition[2]/@operator
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/v11:condition[2]/@value

所以,基本上就是每个元素的XPath,然后是元素Attributes的Xpath.

So, it is basically all the XPath of each element ,then the Xpath of the elements Attributes.

我有一个 XSLT,就像这样:

I have an XSLT with me, which is like this:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" indent="no" />
    <xsl:template match="*[not(child::*)]">
        <xsl:for-each select="ancestor-or-self::*">
            <xsl:value-of select="concat('/', name())" />
            <xsl:if test="count(preceding-sibling::*[name() = name(current())]) != 0">
                <xsl:value-of
                    select="concat('[', count(preceding-sibling::*[name() = name(current())]) + 1, ']')" />
            </xsl:if>
        </xsl:for-each>

        <xsl:apply-templates select="*" />
    </xsl:template>

    <xsl:template match="/">
        <xsl:apply-templates select="*" />
    </xsl:template>

</xsl:stylesheet>

获得 Produced 的输出不适合复杂标签以及结果 Xpath 列表中的标签属性 :(.

THe output which gets Produced does not cater to complex tags and also the tag's attributes in the resulting Xpath list :(.

请帮助我修复此 xslt 以产生上述输出.

Kindly help me in fixing this xslt to produce the output as mentioned above.

上述 XSLT 的当前输出是这样的:

THe present output from the above XSLT is like this :

/v1:Root/v1:UserID
/v1:Root/v1:Destination
/v1:Root/v1:entity/v11:attribute
/v1:Root/v1:entity/v11:attribute[2]
/v1:Root/v1:entity/v11:attribute[3]
/v1:Root/v1:entity/v11:filter/v11:condition
/v1:Root/v1:entity/v11:filter/v11:condition[2]
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter/v11:condition
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/v11:condition
/v1:Root/v1:entity/v11:filter[2]/v11:filter/v11:filter/v11:filter[2]/v11:condition[2]
/v1:Root/v1:entity/v11:filter[2]/v11:filter[2]/v11:filter/v11:condition
/v1:Root/v1:entity/v11:filter[2]/v11:filter[2]/v11:filter[2]/v11:condition
/v1:Root/v1:entity/v11:filter[2]/v11:filter[2]/v11:filter[2]/v11:condition[2]
/v1:Root/v1:entity/v11:filter[2]/v11:filter[2]/v11:filter[2]/v11:condition[3]

推荐答案

我认为您的示例输入和输出之间存在差异,因为输出描述了具有两个 条件的 filter 元素s 不在源 XML 中.无论如何,我相信这是有效的:

I think there's a discrepancy between your sample input and output, in that the output describes a filter element with two conditions that's not in the source XML. At any rate, I believe this works:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no" />
  <!-- Handle attributes -->
  <xsl:template match="@*">
    <xsl:apply-templates select="ancestor-or-self::*" mode="buildPath" />
    <xsl:value-of select="concat('/@', name())"/>
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>

  <!-- Handle non-leaf elements (just pass processing downwards) -->
  <xsl:template match="*[@* and *]">
    <xsl:apply-templates select="@* | *" />
  </xsl:template>

  <!-- Handle leaf elements -->
  <xsl:template match="*[not(*)]">
    <xsl:apply-templates select="ancestor-or-self::*" mode="buildPath" />
    <xsl:text>&#xA;</xsl:text>
    <xsl:apply-templates select="@*" />
  </xsl:template>

  <!-- Outputs a path segment for the matched element: '/' + name() + [ordinalPredicate > 1] -->
  <xsl:template match="*" mode="buildPath">
    <xsl:value-of select="concat('/', name())" />
    <xsl:variable name="sameNameSiblings" select="preceding-sibling::*[name() = name(current())]" />
    <xsl:if test="$sameNameSiblings">
      <xsl:value-of select="concat('[', count($sameNameSiblings) + 1, ']')" />
    </xsl:if>
  </xsl:template>

  <!-- Ignore text -->
  <xsl:template match="text()" />
</xsl:stylesheet>

这篇关于提取所有节点的 Xpath,然后提取它们的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆