XPath按属性值标识所有XML元素,直到运行时才知道

时间:2017-02-17 20:32:25

标签: xml xslt xpath

我有一个XML输入文件,如下所示:

<property>
<properties>
    <entry id="55882d2cacb45">
        <location_number>1</location_number>
        <building_number>1</building_number>
        <coverage source_id="55882d2cacb45">
            <name>building</name>
            <premium>2880</premium>
        </coverage>
        <coverage source_id="55882d2cacb45">
            <name>contents</name>
            <premium>1290</premium>
        </coverage>
        <coverage source_id="55882d2cacb45">
            <name>business</name>
            <premium>7780</premium>
        </coverage>
        <coverage source_id="55882d2cacb45">
            <name>inflationGuard</name>
            <premium>29</premium>
        </coverage>
        <coverage source_id="55882d2cacb45">
            <name>terrorism</name>
            <premium>353</premium>
        </coverage>
        <building>
            <entry id="55882d2cacb45">
                <building>1,000,000</building>
                <coverage_form>Class</coverage_form>
                <coverage source_id="55882d2cacb45">
                    <name>building</name>
                    <premium>2880</premium>
                </coverage>
                <group2_type>Symbol</group2_type>
            </entry>
        </building>
    </entry>
</properties>
<properties>
    <entry id="55882d2cacc68">
        <location_number>1</location_number>
        <building_number>2</building_number>
        <coverage source_id="55882d2cacc68">
            <name>building</name>
            <premium>749</premium>
        </coverage>
        <coverage source_id="55882d2cacc68">
            <name>contents</name>
            <premium>170</premium>
        </coverage>
        <coverage source_id="55882d2cacc68">
            <name>business</name>
            <premium>1095</premium>
        </coverage>
        <coverage source_id="55882d2cacc68">
            <name>inflationGuard</name>
            <premium>7</premium>
        </coverage>
        <coverage source_id="55882d2cacc68">
            <name>terrorism</name>
            <premium>63</premium>
        </coverage>
        <coverage source_id="55882d2cacc68">
            <name>theft</name>
            <premium>266</premium>
        </coverage>
        <building>
            <entry id="55882d2cacc68">
                <building>100,000</building>
                <coverage_form>Class</coverage_form>
                <coverage source_id="55882d2cacc68">
                    <name>building</name>
                    <premium>749</premium>
                </coverage>
                <group2_type>Symbol</group2_type>
            </entry>
        </building>
        <improvements>
            <entry id="55882d2cacc68">
                <improvements>5,000</improvements>
                <coverage_form>Class</coverage_form>
                <coverage source_id="55882d2cacc68">
                    <name>business</name>
                    <premium>1095</premium>
                </coverage>
                <group2_type>Symbol</group2_type>
            </entry>
        </improvements>
    </entry>
</properties>
<eb>
    <eb_total_insured_value>4155000</eb_total_insured_value>
    <coverage source_id="55882d2cacb45">
        <name>eb</name>
        <premium>2880</premium>
    </coverage>
</eb>
<value_pack>
    <coverage source_id="55882d2cacb45">
        <name>capacity_value_pack</name>
        <premium>600</premium>
    </coverage>
</value_pack>
<quote>
    <taxes_fees>
        <coverage source_id="55882d2cacb45">
            <name>mga_fee</name>
            <premium>25</premium>
        </coverage>
        <coverage source_id="55882d2cacb45">
            <name>citizens</name>
            <premium>165.65</premium>
        </coverage>
        <coverage source_id="55882d2cacb45">
            <name>empa</name>
            <premium>4</premium>
        </coverage>
        <coverage source_id="55882d2cacb45">
            <name>fire_surcharge</name>
            <premium>16.57</premium>
        </coverage>
    </taxes_fees>
</quote>

我需要找到所有元素,无论名称如何,都具有与entry元素的'id'属性匹配的source_id属性(请参阅第一个条目元素)并单独处理它们。在运行时之前,该值是未知的。使用密钥似乎是答案的一部分,但元素名称似乎在我能找到的所有示例中都是硬编码的。欣赏任何见解!

2 个答案:

答案 0 :(得分:1)

这个XPath,

//*[@source_id = ancestor::entry/@id]

将选择source_id属性值等于祖先entry元素的@id属性值的所有元素。

答案 1 :(得分:0)

如果您了解密钥,可以使用<xsl:key name="source" match="*[@source_id]" use="@source_id"/>为具有source_id属性的所有元素定义密钥。然后从<xsl:template match="entry">您可以使用例如key('source', @id)查找所有引用的元素,甚至在XSLT 2 key('source', @id, .)中查找条目的所有引用的后代元素