我使用下面的代码从xml中删除名称空间属性,但我没有成功。我想仅从节点 Action__CompIntfc__CIName
删除名称空间<Action__CompIntfc__CIName xmlns="http://schemas.xmlsoap.org/soap/encoding/">
以下是我的代码
procedure TForm1.Button1Click(Sender: TObject);
var
xmldoc : IXMLDOMDocument;
xmlString : WideString;
RecNodelist: IXMLDOMNodeList;
DataNode: IXMLDOMElement;
attr : IXMLDOMAttribute;
begin
xmlString := '<?xml version="1.0"?>'
+'<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">'
+'<SOAP-ENV:Body>'
+'<Action__CompIntfc__CIName xmlns="http://schemas.xmlsoap.org/soap/encoding/">'
+'<test>1</test>'
+'</Action__CompIntfc__CIName>'
+'<Action__CompIntfc__CIName xmlns="http://schemas.xmlsoap.org/soap/encoding/">'
+'<test>15</test>'
+'</Action__CompIntfc__CIName>'
+'</SOAP-ENV:Body>'
+'</SOAP-ENV:Envelope>';
try
XMLdoc := CoDOMDocument.Create;
xmldoc.loadXML(xmlString);
RecNodelist := XMLdoc.selectNodes('//SOAP-ENV:Envelope/SOAP-ENV:Body/Action__CompIntfc__CIName');
DataNode := RecNodelist.NextNode as IXMLDOMElement;
while DataNode <> nil do
begin
showmessage(DataNode.xml);
attr := DataNode.getAttributeNode('xmlns');
DataNode.removeAttributeNode(attr);
showmessage(DataNode.xml);
DataNode := RecNodelist.NextNode as IXMLDOMElement;
end;
except
on e: Exception do
begin
ShowMessage(e.Message);
end;
end;
end;
删除命名空间&#34; xmlns =&#34; http://schemas.xmlsoap.org/soap/encoding/"来自节点下面的XML
<Action__CompIntfc__CIName xmlns="http://schemas.xmlsoap.org/soap/encoding/">
我期待我的xml
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<Action__CompIntfc__CIName>
<test>1</test>
</Action__CompIntfc__CIName>
<Action__CompIntfc__CIName>
<test>15</test>
</Action__CompIntfc__CIName>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
答案 0 :(得分:2)
作为DOM编程的替代方案,这里有一个XSLT 1.0样式表可以完成这项工作:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:se="http://schemas.xmlsoap.org/soap/encoding/" exclude-result-prefixes="se">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="se:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:transform>
它转换
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<Action__CompIntfc__CIName xmlns="http://schemas.xmlsoap.org/soap/encoding/">
<test>1</test>
</Action__CompIntfc__CIName>
<Action__CompIntfc__CIName xmlns="http://schemas.xmlsoap.org/soap/encoding/">
<test>15</test>
</Action__CompIntfc__CIName>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
进入
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<Action__CompIntfc__CIName>
<test>1</test>
</Action__CompIntfc__CIName>
<Action__CompIntfc__CIName>
<test>15</test>
</Action__CompIntfc__CIName>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
如http://xsltransform.net/94rmq6V/1所示。
至于将它与MSXML一起使用,您可以将transformNodeToObject
,https://msdn.microsoft.com/en-us/library/ms766561%28v=vs.85%29.aspx与输入文档一起使用,将第二个文档加载到样式表和结果文档之上,如
var
xmldoc : IXMLDOMDocument;
sheet : IXMLDOMDocument;
result : IXMLDOMDocument;
并创建它们:
xmldoc := CoDOMDocument.Create;
sheet := CoDOMDocument.Create;
result := CoDOMDocument.Create;
像你一样加载xmldoc,加载上面的XSLT代码(使用load
方法从文件中加载,或者加载loadXML
的字符串,就像你对xmldoc一样),然后调用
xmldoc.transformNodeToObject(sheet, result);
答案 1 :(得分:1)
以下适用于我。
正如您将看到的,它通过迭代您的RecNodeList
寻找具有正确名称的节点来工作。当它找到一个时,它会创建一个具有相同tagName
和text
属性的新节点,复制除“xmlns”之外的其属性,然后用新的节点替换现有节点。
它还复制节点的第一级子节点及其属性。如果你想复制那些子节点的子节点(如果有的话),那么编写递归函数可能最容易,但是q中的Xml不会出现这种情况。
当然,所示方法对Xml文档的结构很敏感,因此非常脆弱。我没有试图找出答案,但我认为评论中提出的XSLT解决方案可能同样脆弱。
procedure TForm1.RemoveNS;
var
xmldoc : IXMLDOMDocument;
xmlString : WideString;
Target : String;
RecNodelist: IXMLDOMNodeList;
DataNode: IXMLDOMElement;
NextNode : IXMLDOMNode;
NewNode: IXMLDOMElement;
AttrNode : IXMLDOmNode;
ChildNode : IXMLDomElement;
Map : IXMLDOMNamedNodeMap;
i,
j : Integer;
begin
// remove Namespace only from nodes
// <Action__CompIntfc__CIName xmlns="http://schemas.xmlsoap.org/soap/encoding/">
xmlString := '<?xml version="1.0"?>'#13#10
+'<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">'#13#10
+'<SOAP-ENV:Body>'#13#10
+'<Action__CompIntfc__CIName xmlns="http://schemas.xmlsoap.org/soap/encoding/" anattr="hello">'#13#10
+'<test attr="123">1</test>'#13#10
+'</Action__CompIntfc__CIName>'#13#10
+'<Action__CompIntfc__CIName xmlns="http://schemas.xmlsoap.org/soap/encoding/">'#13#10
+'<test>15</test>'#13#10
+'</Action__CompIntfc__CIName>'#13#10
+'</SOAP-ENV:Body>'#13#10
+'</SOAP-ENV:Envelope>'#13#10;
Memo1.Lines.Text := xmlString;
Target := 'Action__CompIntfc__CIName';
xmldoc := CoDOMDocument.Create;
try
xmldoc.loadXML(xmlString);
RecNodelist := xmldoc.selectNodes('//SOAP-ENV:Envelope/SOAP-ENV:Body/Action__CompIntfc__CIName');
DataNode := RecNodelist.NextNode as IXMLDOMElement;
while DataNode <> nil do
begin
NextNode := DataNode.nextSibling;
if CompareText(DataNode.nodeName, Target) = 0 then begin
NewNode := XMLDoc.createElement(DataNode.tagName);
NewNode.text := DataNode.Text;
// copy the existing node's Attributes
Map := DataNode.attributes;
for i := 0 to Map.length - 1 do begin
AttrNode := Map.item[i];
if CompareText(AttrNode.NodeName, 'xmlns') <> 0 then
NewNode.SetAttribute(AttrNode.NodeName, AttrNode.NodeValue);
end;
// Create (first level) child nodes matching the existing node's
// children and any attributes they have
for i := 0 to DataNode.childNodes.length - 1 do begin
ChildNode := XMLDoc.createElement(DataNode.childNodes.item[i].nodeName);
ChildNode.text := DataNode.childNodes.item[i].Text;
Map := DataNode.childNodes.item[i].attributes;
for j:= 0 to Map.length - 1 do begin
AttrNode := Map.item[j];
ChildNode.SetAttribute(AttrNode.NodeName, AttrNode.NodeValue);
end;
NewNode.appendChild(ChildNode);
end;
DataNode.parentNode.replaceChild(NewNode, DataNode);
end;
DataNode := NextNode as IXmlDOMElement;
end;
Memo2.Lines.Text := XmlDoc.documentElement.xml;
except
on e: Exception do
begin
ShowMessage(e.Message);
end;
end;
xmldoc := Nil; // not strictly necessary because it will get finalized when this procedure exits, but anyway
end;