代码之家  ›  专栏  ›  技术社区  ›  Pablo Bastidas

如何处理“<?”使用Python在xml文件中进行注释

  •  2
  • Pablo Bastidas  · 技术社区  · 7 年前

    有人知道如何用Python处理这种XML注释,这是我第一次看到它。

    &lt;?link id="752760" resource-uuid="UUID-9f0575a3-1847-1cde-fd35-f18014fdecf3" resource-id="570935" resource-type="fork" type="ResourceLink"?&gt;
    

    我需要查询此类“元素”以获取 resource-uuid 价值

    4 回复  |  直到 4 年前
        1
  •  2
  •   Daniel Haley    4 年前

    感谢大家,我了解了处理指令,并以此为基础研究了如何处理它,下面,如果有人需要的话,我就让我自己动手:

    from lxml import etree
    
    ...
    
    file = 'path/to/file.xml'
    tree = etree.parse(file)
    result = tree.xpath('//processing-instruction("link")')
    for pi in result:
        # Each pi is a processing instruction tagged as 'link'
        if pi.get('type').__str__() == 'ResourceImport':
            # PI with type = ResourceImport
            print pi.text # Check the text of tis PI
    

    使用 lxml 库使用XPath很容易获得处理指令。

    我希望这个代码片段能帮助那些因为这个问题而来到这里的人。

        2
  •  1
  •   Gottfried Lesigang    7 年前

    您必须区分 处理说明 以及 xml声明

    两者的书写方式相同: <?SomeName SomeContent ?>

    发现 details in section 2.6 哦!

    而xml声明必须放在首位,并以 <?xml 其他处理指令可能(几乎)出现在XML中的任何位置。

    处理指令必须有名称,而内容不像元素的内容那样受到正式限制。这是免费文本。。。

    这就是格式良好的XML:

    <root>
      <a>test</a>
      <?piName some test?>
    </root>
    

    我不使用python,但这将返回SQL Server中的PI:

    DECLARE @xml XML=
    N'<root>
        <a>test</a>
        <?link id="752760" resource-uuid="UUID-9f0575a3-1847-1cde-fd35-f18014fdecf3" resource-id="570935" resource-type="fork" type="ResourceLink"?>
      </root>';
    
    SELECT @xml.query('/root/processing-instruction("link")');
    

    即使您的内容看起来像 属性 :PI中的内容是自由文本。所以你必须从内容中解析你的信息。。。

    This answer 可能对你有帮助。

        3
  •  0
  •   Christian Grün    7 年前

    如果您的处理器支持XQuery 3.1,以下是解决此问题的一种方法:

    declare function local:values($pi) {
      map:merge(
        for $pair in tokenize($pi)
        let $key := substring-before($pair, '=')
        let $value := replace(substring-after($pair, '='), '^"|"$', '')
        return map:entry($key, $value)
      )
    };
    
    let $xml := document {
      <xml>
        <?link id="752760" resource-uuid="UUID-9f0575a3-1847-1cde-fd35-f18014fdecf3"
          resource-id="570935" resource-type="fork" type="ResourceLink"?>
      </xml>
    }
    for $pi in $xml//processing-instruction('link')
    let $values := local:values($pi)
    return $values?resource-uuid
    

    针对旧版本XQuery的又一个解决方案:

    let $xml := document {
      <xml>
        <?link id="752760" resource-uuid="UUID-9f0575a3-1847-1cde-fd35-f18014fdecf3"
          resource-id="570935" resource-type="fork" type="ResourceLink"?>
      </xml>
    }
    for $pi in $xml//processing-instruction('link')
    for $pair in tokenize($pi, '\s+')[substring-before(., '=') = 'resource-uuid']
    return replace(substring-after($pair, '='), '^"|"$', '')
    

    这两个代码段都是在这样的假设下工作的,即处理指令中的值都是由示例中的值组成的(键和值用等号分隔,值用双引号括起来)。

        4
  •  0
  •   Mads Hansen    6 年前

    您引用的“注释”称为 processing instruction

    在处理指令时,使用 keyword="value" 语法类似于XML元素的属性,但不幸的是,这只是一种约定,不是XML固有的东西,因此您必须自己解析内容以提取属性。(Saxon有一个函数 saxon:get-pseudo-attribute() 为此)。

    如果您使用的是Python,那么在Python代码而不是XPath代码中执行这一额外的解析阶段可能会更简单,除非您实际上需要将该值作为某个更大的XPath表达式的一部分,在这种情况下,详细信息取决于您是使用XPath还是XQuery以及使用哪个版本。