【问题标题】:XML Entity in setAttribute/addAttributesetAttribute/addAttribute 中的 XML 实体
【发布时间】:2012-01-04 05:25:17
【问题描述】:

好吧,也许我错过了一些简单的东西。我一直在寻找很长一段时间,但没有运气。我需要在 XML 属性中插入一个实体。为了做到这一点,我需要能够将 & 与 DOM 类的 setAttribute 方法结合使用(或 addAttribute 用于 simpleXML 类)。当我尝试使用它时,它会转义与符号,因此&entity; 变为&entity;。尝试手动转义与符号\&entity; 只会导致\&entity;。输入与号实体&entity; 只是将其翻倍&entity;。我理解它为什么这样做,如果没有与有效实体关联,& 符号会破坏 XML。问题是,它与一个实体相关联,我不知道如何使用它。

我找到了createEntityReferenceDOMEntityReference 方法,但是这些方法的文档很差,我不确定这些是否是我需要的。谷歌搜索这些术语似乎只显示相同的 PHP 文档,但来自不同的站点。我试过单独搜索这个问题,但我只是得到解释我已经知道并在上面指出的结果。我已经尝试过 DOM 和 SimpleXML,但都产生了相同的结果。我只是过于复杂了,还是真的不支持?

【问题讨论】:

    标签: php xml dom entity simplexml


    【解决方案1】:

    坦率地说,对我来说这是一个具有挑战性的问题,因为我自己没有想到它,虽然答案很简单:

    根据甚至Level 1 of the DOM recommendation接口Attr继承了Node接口,也就是说你可以将节点附加到一个属性。并且EntityReference 允许在Attr 孩子中。

    在 XML 中,属性的值可以包含实体引用,Attr 节点的子节点提供不扩展实体引用的表示。这些子节点可以是 Text 或 EntityReference 节点。因为属性类型可能未知,所以没有标记化的属性值。

    这是一个 PHP 的工作示例:

    <?php
    
    // a valid XML should contain used entities declarations to be valid,
    // but DOM recs do not contain means to generate DTD;
    // in PHP you can use XMLWriter for the purpose though 
    $dtd = <<<DTD
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE root [
      <!ENTITY my_entity "some content">
    ]>
    <root/>
    DTD;
    
    $xml = new DOMDocument();
    $xml->formatOutput = true;
    
    $xml->loadXML($dtd);
    
    $root = $xml->documentElement;
    
    $entity = $xml->createEntityReference( 'my_entity' );
    
    $an_attr = $xml->createAttribute( 'attr' );
    $an_attr->appendChild( $xml->createTextNode('prefix ') );
    $an_attr->appendChild( $entity );
    $an_attr->appendChild( $xml->createTextNode(' suffix') );
    $root->setAttributeNode( $an_attr );
    
    // clone the entity to use it more than once
    $root->appendChild( $entity->cloneNode() );
    
    print $xml->saveXML();
    
    ?>
    

    导致

    C:\>\php\5.3.8\php.exe entities.php
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE root [
    <!ENTITY my_entity "some content">
    ]>
    <root attr="prefix &my_entity; suffix">&my_entity;</root>
    

    【讨论】:

    • 像魅力一样工作。谢谢你。你解决了一个困扰我好几天的问题。我会指出,如果其他人偶然发现这一点,如果您想再次使用它,您需要在附加后重新创建实体引用和属性节点。
    • @showerhead,您可以克隆节点,而不是重新创建节点。此外,我的示例生成了无效的 XML(缺少实体声明)。我更新了示例以反映问题。我不介意将此添加到文档中,谢谢。
    • 谢谢,我没想到克隆。需要注意的是,DOM 限制了 DTD 交互。它不能像 XMLWriter 那样创建它,但它可以通过DOMImplementation::createDocumentType 引用它。
    猜你喜欢
    • 2013-01-27
    • 2010-10-07
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多