难以通过属性选择节点的子节点

时间:2015-03-05 23:39:11

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

我在选择s:latin

s:fontSlot子节点时遇到问题
<?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变量正确返回,在本例中为&#34; title&#34;。

我试过了:

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

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

这两个都没有返回。但是,当我console.log以下时,我注意到了这一点:

$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,并且我还尝试了上述命名空间选择器的非转义版本。

1 个答案:

答案 0 :(得分:1)

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

Chrome中的

find()children()似乎在命名空间方面的工作方式不同。但Firefox对所有方法都是一致的

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

奇怪的是,两个浏览器的日志记录node.tagNames: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