【问题标题】:How to create an XML text node with an empty string value (in Java)如何使用空字符串值创建 XML 文本节点(在 Java 中)
【发布时间】:2011-04-22 13:01:15
【问题描述】:

我正在使用Transform 对象来保存我的 XML 文件,但它似乎删除了空文本节点。有什么方法可以创建(并保留)带有空字符串的文本节点,即“”。

这是我创建节点的方式:

Element type = doc.createElement("TYPE");

type.appendChild(doc.createTextNode(value));

只是有时value 是一个空字符串“”。当我使用文本编辑器查看 XML 时,我看到了

<TYPE />

而不是

<TYPE></TYPE>

在我读回这个 XML 文件并遍历节点后, 元素根本没有任何子元素,即使我为它显式创建了一个#text 节点!

编辑 - 感恩节快乐(我的加拿大同胞)

重要提示,我不是从一组已知的标签开始工作,而是我正在处理的程序使用文本节点的存在来为 GUI 分配一个JTextField。只是有时该字段为空(不是空,而是“”)。当我存储该字段然后将其读回时,GUI 不再呈现JTextField,因为没有文本节点。因此,我正在寻找创建 XML 文档的方法,该文档会创建一个文本节点,即使其中没​​有任何内容。如果这根本不能用 XML 完成,那么我将不得不使用一个属性来标记可编辑的标签(有点像 Andrey Breslav 建议的),因此应该分配一个 JTextField

我会尝试 Mads Hansen 提出的不间断空间的建议。

【问题讨论】:

  • 等价于

标签: java xml


【解决方案1】:

文本节点没有文本 不是文本节点

如果您尝试控制 XML 元素的序列化方式,&lt;TYPE/&gt;&lt;TYPE&gt;&lt;/TYPE&gt; 是等价的,如果使用其中任何一个对 XML 处理器来说都无关紧要。两者都声明了一个没有任何text() 的 TYPE 元素。大多数处理器会将空元素序列化为自闭合元素。

如果你真的想防止元素被序列化为自闭合,你可以变得可爱并添加一个零宽度空间作为文本节点值: &lt;TYPE&gt;&amp;#x200B;&lt;/TYPE&gt; 看起来像:&lt;TYPE&gt;&lt;/TYPE&gt;

从技术上讲,它不是“空”字符串,但可能会达到您想要的效果,并且如果选择并使用文本节点,则不会填充空格。

【讨论】:

  • 这正是我想要的。我不得不更改我的焦点侦听器以用 ​ 替换空字符串但这有点微不足道。唯一的主要缺点是,如果有人手动编辑 XML 文件并忘记在空白字段中放置不间断空格,它会弄乱我的 GUI - 但我可以忍受 :)
【解决方案2】:

从 XML 的角度来看,&lt;TYPE/&gt;&lt;TYPE&gt;&lt;/TYPE&gt; 之间没有区别。两者是等效的,可以互换使用。对于 XML 解析器,这意味着没有文本。解析器不区分“无文本”和“零长度文本”。

相比之下,Java 的null"" 是完全不同的概念。

因此,如果您想从 Java 值映射到 XML,反之亦然,您必须处理这种不匹配。并且有几种可能的选择。例如,您可以放弃 String 变量的 null 值。然后你必须确保你所有的 String 变量都是用空字符串初始化的。或者你可以说一个没有文本子元素的 TYPE 元素(序列化为 &lt;TYPE/&gt;&lt;TYPE&gt;&lt;/TYPE&gt;)在 Java 中表示空字符串,缺少的 TYPE 元素代表null。这是你的选择。

【讨论】:

    【解决方案3】:

    这是您要查找的代码:

    try{
        DocumentBuilderFactory docFactory=DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder=docFactory.newDocumentBuilder();
    
        //root Elements -- Response
        Document doc=docBuilder.newDocument();
        doc.setXmlStandalone(true);
        Element response=doc.createElement("Data");
        doc.appendChild(response);
    
        // Child Element -- Play
        Element hangup=doc.createElement("Type");
        response.appendChild(hangup);
    
        //Writer the content into xml file
        TransformerFactory transformerFactory=TransformerFactory.newInstance();
        Transformer transformer=transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT,"yes");
    
        DOMSource source=new DOMSource(doc);
        StreamResult result=new StreamResult(sayOut);
        //StreamResult result=new StreamResult(System.out);
    
        transformer.transform(source,result);
        logger.info("===========XML GENERATION DON FOR HANGUP============");
    
    }catch(ParserConfigurationException pce){
        logger.error(" ==============2======== ERROR IN PRASERCONFIGURATION ===================================");
        pce.printStackTrace();
    }
    

    由它生成的输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <Data>
    <Type/>
    </Data>
    

    希望我给出了正确的东西......虽然我同意 &lt;Type/&gt;&lt;Type&gt;&lt;/Type&gt; 在 XML Parser 方面没有区别。

    【讨论】:

      【解决方案4】:

      我会选择字符串属性而不是标签内容。另一种选择是使用内容,但在内容为空字符串的情况下放置一个属性。

      【讨论】:

      • 我试过了,它确实有效,但使 XML 文件大了大约 20%,而且 IMO 看起来不正确。
      【解决方案5】:

      如果您考虑 XML specs,则在 有效 字符集中并没有真正定义空字符串 ''。因此文档构建器可能会简单地忽略任何出现的无效字符。

      【讨论】:

        【解决方案6】:

        我遇到过类似的问题,当重新解析 XML 时,&lt;Element /&gt; 被视为 null,而我需要的是 &lt;Element&gt;&lt;/Element&gt;,因此它将被解析为空字符串。我最终通过向它添加一个空的评论节点来解决这个问题,所以它最终看起来像这样&lt;Element&gt;&lt;!----&gt;&lt;/Element&gt;

        对不起,如果这不能直接回答问题,但这是谷歌上的最佳答案,所以认为有人可能会觉得这很有用。

        【讨论】:

          【解决方案7】:

          你应该用

          注释你的字段
          @XmlElement(nillable=true)
          

          只需将其设置为 null,您将获得:

          <TYPE xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
          

          表示元素为空。

          否则,如果您只想打开和关闭标签,只需将其值设置为“”(空字符串)。你会得到:

          <TYPE></TYPE>
          

          【讨论】:

          • 不,这不起作用,OP在问题中明确表示,“有时值是一个空字符串”。当我用文本编辑器查看XML时,我看到@ 987654324@ 而不是 &lt;TYPE&gt;&lt;/TYPE&gt;。"
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-11-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-23
          • 1970-01-01
          • 2017-01-30
          相关资源
          最近更新 更多