【问题标题】:Specify an XML Closing tag in Java (it auto <Self-Closes/> for empty elements) -or- Syntax to contain child nodes under specified parent branches?在 Java 中指定一个 XML Closing 标记(它自动 <Self-Closes/> 用于空元素) - 或 - 包含指定父分支下的子节点的语法?
【发布时间】:2015-01-23 01:02:45
【问题描述】:

我在尝试强制 XML SOAP 请求的结束标签时遇到问题,因为 Java 会自动生成自结束标签。这会导致包含问题并导致无效的子元素错误。下面显示了用于在 XML 中制作 SOAP 主体的代码。 “请求”中有几个节点没有值,但服务器确实保存了数据。下面显示了我得到的输出和我需要什么。今天是我玩 Java 的第一天,所以请用超级简单的术语解释一下,或者更好的是,显示一个示例代码行。我读了一篇类似标题的帖子,但似乎是用不同的语言写的。感谢您的帮助。

更新:在 w3schools 网站上它声明:

"空 XML 元素 - 可以为没有内容的 XML 元素使用另一种语法:而不是像这样编写 book 元素(没有内容):&lt;book&gt;&lt;/book&gt; 可以这样写this &lt;book /&gt; 这种元素语法称为自闭合。”

所以,表达我的请求的另一种方式是,如何防止 Java 编译器编译自关闭 XML 元素以避免错误:“Invalid Subelement Worker_Reference-urn:com.workday/bsvc for element Get_Workers_Request (6$16639 )”。我需要指定元素/子节点应该在树中的哪个位置关闭,因为这样可以解决我在其他语言(例如 VB)中复制它时的问题。

//---------------------------------------------------------------------------
//*************** This is the body code *************** ---------------------
//---------------------------------------------------------------------------

    SOAPBody soapBody = envelope.getBody();
    SOAPElement soapBodyElem = soapBody.addChildElement("Get_Workers_Request", "wd", "urn:com.workday/bsvc");
    SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("Request_References", "wd");
    SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("Worker_Reference", "wd");
    SOAPElement soapBodyElem3 = soapBodyElem.addChildElement("ID", "wd");
    soapBodyElem3.setAttribute("wd:type", "Employee_ID");
    soapBodyElem3.addTextNode("123");



//---------------------------------------------------------------------------
//*************** This is what I get *************** ------------------------
//---------------------------------------------------------------------------

     <SOAP-ENV:Body>
        <wd:Get_Workers_Request>
            <wd:Request_References/>
                <wd:Worker_Reference/>
                    <wd:ID wd:type="Employee_ID">123</wd:ID>

        </wd:Get_Workers_Request>


//----------------------------------------------------------------------------
//*************** This is what I need *************** ------------------------
//----------------------------------------------------------------------------

     <SOAP-ENV:Body>
        <wd:Get_Workers_Request>
            <wd:Request_References>
                <wd:Worker_Reference>
                    <wd:ID wd:type="Employee_ID">123</wd:ID>

                </wd:Worker_Reference>
            </wd:Request_References> 
        </wd:Get_Workers_Request>

更新 #2:

这是来自 Microsoft VB 代码的复制和粘贴,其中包含所做的确切更改以及此摘录的结果。缺乏遏制复制了这种失败。

sEnv = sEnv & "<wd:Request_References>"
sEnv = sEnv & "<wd:Worker_Reference>"
sEnv = sEnv & "<wd:ID wd:type=""Employee_ID"">" & sEmployee_ID & "</wd:ID>"
sEnv = sEnv & "</wd:Worker_Reference>"
sEnv = sEnv & "</wd:Request_References>"
'--------------------------
'Returns value - John Smith
'--------------------------


sEnv = sEnv & "<wd:Request_References/>"
sEnv = sEnv & "<wd:Worker_Reference/>"
sEnv = sEnv & "<wd:ID wd:type=""Employee_ID"">" & sEmployee_ID & "</wd:ID>"
 'sEnv = sEnv & "</wd:Worker_Reference>"
 'sEnv = sEnv & "</wd:Request_References>"
'------------------------------------------------------------------------
'Returns Error - Invalid Subelement ID-urn:com.workday/bsvc for element Get_Workers_Request (6$16639)
'------------------------------------------------------------------------

【问题讨论】:

  • 您是否编辑或尝试重新输入“这就是我得到的”XML?你声称得到的和你声称需要的都不是well-formed XML。
  • @kjhughes - 是的,这是我为说明问题而编辑的摘录。 java 编译器会看到任何没有与之关联的值的子节点,并在子节点的末尾附加一个正斜杠。如果我从我的工作 VB 代码中获取一个子条目(例如)并将“/”放在末尾 ,它会失败并显示错误“Invalid Subelement ID-urn:com.workday/bsvc for element Get_Workers_Request (6$16639)" 就像现在在 Java 中一样。我需要的是结束标记 被强制以 Java 和适当的位置显示。谢谢
  • 在 w3schools 网站上它声明为空 XML 元素 - 可以为没有内容的 XML 元素使用另一种语法:而不是像这样编写 book 元素(没有内容): 可以这样写 这种元素语法称为自闭合。
  • 如果您试图避免自闭合元素,您就问错了问题。 &lt;book/&gt;&lt;book&gt;&lt;/book&gt; 是完全等价的。 XML 处理器将以相同的方式处理它们。请阅读XML with end tag and without it 接受的答案。谢谢。
  • @kjhughes - 我很感谢您的回复。对于一个空的末端叶节点来说,这似乎意味着相同,但是当它与主分支绑定时,它每次都会失败。我有可以在 VB 中运行的工作代码,现在刚刚对其进行了测试。一旦我将 替换为仅 用于空的主分支,它就会失败并显示相同的消息“无效的子元素”。有什么想法吗?

标签: java xml soap tags


【解决方案1】:

如何强制 XML 有结束标签?

你没有。

您误解了错误。 它与自闭合标签无关。 &lt;e&gt;&lt;/e&gt;&lt;e/&gt; 在 XML 中是完全等价的。 XML 处理器将同等对待每个表单。一种形式不会出错,而另一种形式不会出错。如果一个是对的,那么他们两个都是对的。另见XML with end tag and without it

改为查看您正在组装的元素的实际组成。您的错误消息为您指明了正确的方向:

Invalid Subelement xxxxxx for element Get_Workers_Request (6$16639)

您在不应该出现的位置向 Get_Workers_Request 添加了 xxxxxx。 (顺便说一句,您到底为什么要屏蔽该名称?)除了有用的验证消息之外,请检查定义 Get_Workers_Request 预期结构的架构以获得进一步的指导。

关于更新#2

在您的更新 #2 代码中,两个构造的请求甚至不接近相等,它们根本不支持您声称您的问题源于 &lt;e&gt;&lt;/e&gt;&lt;e/&gt; 之间的差异:

  • 在有效的那个中,wd:Request_References 包含 wd:Worker_Reference
  • 在失败的wd:Request_References precedes wd:Worker_Reference

即使您从这个答案中没有学到任何其他东西,如果您根据 元素包含 而不是 来思考、编码和调试,那么您将领先一步>标签关闭.

【讨论】:

  • 感谢@kjhughes,我在上面添加了更新#2,它是我的 VB 代码的复制和粘贴,其中包含所做的确切更改和确切的输出。请参考,也许您可​​以帮助我确定问题?我错过了什么吗?
  • 关于更新 #2 - 是的,没错!这就是问题,一个包含,另一个在先。 Java 查看我的请求并“强制”我的请求先于而不是包含。因此,我最初的问题是,如何在需要创建遏制的项目“之后”强制结束标签。此请求不是针对根分支和主分支上没有任何内容的 XML 文件,而是从子节点的每个主分支上的数百万个数据点中查询单个数据。
  • 只是想说非常感谢@kjhughes,因为我真的很感谢你花时间和我一起解决这个问题——我一开始就意识到我最初的问题可能很模糊,所以很好有你的帮助进一步定义它 - 关于更新#2 - 是的,完全正确!这就是问题,一个包含,另一个在先。 Java 查看我的请求并“强制”我的请求先于而不是包含。因此,我最初的问题是,如何在我需要创建遏制的项目“之后”强制结束标签。
  • 抱歉,但如果同意我关于更新 #2 的评论导致您因此我的原始问题(?!),我无法进一步帮助您。祝你好运。
  • 我很困惑,是的,我同意我对 XML 有包容性问题,但请记住,这个问题是由于缺乏对形成 XML 的控制,因为 Java 是自动的形成关闭。我问错问题了吗? Java 是否有一个技巧,Java 会在我需要的地方自动关闭以进行遏制?在一天结束时,我说我是 Java 的新手,如果有人可以帮助获取我发布的原始代码并使输出看起来像我需要的那样。你为什么不帮忙?似乎是一个明显的问题,我让你同意这个问题。
【解决方案2】:

您说“它”返回错误Invalid Subelement ID-urn:com.workday/bsvc for element Get_Workers_Request (6$16639)。但“它”是什么?在我看来,它就像某种过程,它根据某种模式验证您生成的 XML。在不知道这个验证器是什么或架构是什么的情况下,很难说得更具体一些,但我认为您几乎可以肯定地认为它是由使用自闭合标签引起的,因此您是在找错树。

【讨论】:

  • 感谢您的回复 Michael - Java 查看我的请求并“强制”我的请求先于而不是包含(请参阅前面的更新答案)。因此,我最初的问题是,如何在需要创建遏制的项目“之后”强制结束标签。此请求不是针对根分支和主分支没有任何内容的 XML 文件,而是从子节点的每个主分支的数百万个数据点中查询单个数据
【解决方案3】:

当我在上面尝试的最后一个回复中提到它时,我想我错过了其中一个要参考的数字。对于任何挣扎的人......这就是修复它的方法。通过引用soapBodyElem1 和 2,它将结束标签移动到我需要它的位置。它们不再在同一行上自行关闭标签,而是将所需的元素封装在它们下方。

SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("Get_Workers_Request", "wd", "urn:com.workday/bsvc");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("Request_References", "wd");
SOAPElement soapBodyElem2 = soapBodyElem1.addChildElement("Worker_Reference", "wd");
SOAPElement soapBodyElem3 = soapBodyElem2.addChildElement("ID", "wd");
soapBodyElem3.setAttribute("wd:type", "Employee_ID");
soapBodyElem3.addTextNode("123");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-30
    • 2020-07-29
    • 2013-08-24
    • 1970-01-01
    • 2015-05-15
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多