【问题标题】:Difficulty getting child of node selected with attribute难以使用属性选择节点的子节点
【发布时间】:2015-03-05 23:39:11
【问题描述】:

我在选择s:fontSlots:latin 子节点时遇到问题

<?xml version="1.0" encoding="utf-8" ?>
<s:fontScheme name="CustomFontFamily" previewSlot1="title" previewSlot2="body" xmlns:s="http://schemas.microsoft.com/sharepoint/">
    <s:fontSlots>
        <s:fontSlot name="title">
            <s:latin typeface="Segoe UI Light" />
            <s:ea typeface="" />
            <s:cs typeface="Segoe UI Light" />
            <s:font script="Arab" typeface="Segoe UI Light" />
            ...
        </s:fontSlot>
        ...
    </s:fontSlots>
</s:fontScheme>

请记住,这仅适用于 Google Chrome,而且似乎更喜欢 all namespaces be dropped

文档被正确解析和包装:

var $xml = $($.parseXML(xml));

slot.name 变量正确返回,在本例中为“title”。

我试过了:

$xml.find('fontSlot[name="' + slot.name + '"] latin')

$xml.find('fontSlot[name="' + slot.name + '"]').children('latin')

这两个都没有返回。但是,我注意到当我 console.log'd 时:

$xml.find('fontSlot[name="' + slot.name + '"]')

找到正确的父节点,并且:

$xml.find('fontSlot[name="' + slot.name + '"]').children()

返回节点列表,包括s:latin。然后我尝试过滤:

$xml.find('fontSlot[name="' + slot.name + '"]').children().filter('latin')

这不返回任何内容。所以我决定尝试使用命名空间:

$xml.find('fontSlot[name="' + slot.name + '"]').children().filter('s\\:latin')

而且这实际上返回了所需的节点!所以我回去尝试简化:

$xml.find('fontSlot[name="' + slot.name + '"] s\\:latin')

再一次,什么都没有。我可以稍微简化一下:

$xml.find('fontSlot[name="' + slot.name + '"]').find('latin')

我仍然觉得第一次尝试应该会奏效。为什么不呢?对我来说,这似乎是 jQuery/Sizzle 中的一个错误。还是我错过了什么?

其他细节:我使用的是 jQuery 2.1.1,并且我还尝试了上述命名空间选择器的非转义版本。

【问题讨论】:

    标签: javascript jquery xml google-chrome google-chrome-extension


    【解决方案1】:

    我同意选择器对于不同的方法和不同的浏览器的行为似乎不同。

    find()children() 作为 Chrome 中的示例,在命名空间方面似乎有所不同。 Firefox 对所有方法都是一致的

    虽然 Chrome 不喜欢 s\\:fontSlot,但 Firefox 本身不喜欢 fontSlot

    奇怪的是,两个浏览器记录node.tagName输出的格式相同,s:tagName格式。

    玩了一会儿,似乎唯一安全的跨浏览器方法是每次遍历使用 2 个选择器:

    var slot={name:'title'};    
    $.post('/echo/xml/', {xml: xml}, function(xml){        
        $(xml).find('s\\:fontSlot, fontSlot').children('s\\:latin, latin').each(function(){
           console.log(this.tagName); //s:latin in both chrome and FF
        });        
    },'xml');
    

    DEMO

    【讨论】:

    • 我不关心 Firefox,虽然信息很有趣。不幸的是,这个答案并没有解决我为什么第一次 find 调用失败的主要问题。
    • 我确实认为这是一个错误,不确定是 Chrome 还是 jQuery,但如果你一直使用这两个选择器,我认为它会起作用。不确定你指的是哪个first
    • 我指的是:$xml.find('fontSlot[name="' + slot.name + '"] latin') 我在单个查找中使用简单的祖先后代选择器。我已经测试了您的建议,它确实有效,但它并不像应该的那么简单。但看起来 filterchildren 工作方式相同(需要命名空间)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多