我在重命名XML元素名称时遇到麻烦。我正在尝试实现以下目标。
输入:
if(getIntent().getIntExtra("number",-1) ==2)
{
// what do you want to do...
}
预期输出:
<Addresses>
<AddressItem>
<AddressLine1>RZN850PXKYG</AddressLine1>
<AddressLine2>RYK57IT7Y9Z</AddressLine2>
<AddressType>Physical</AddressType>
<City>Some City</City>
<PostalCode>9999</PostalCode>
<Province>Some Province</Province>
<Suburb>Some Suburb</Suburb>
</AddressItem>
</Addresses>
以前,我已经使用类似的方法成功添加了属性并重命名了元素:
<b:Addresses>
<b:AddressItem>
<b:AddressLine1>RZN850PXKYG</b:AddressLine1>
<b:AddressLine2>RYK57IT7Y9Z</b:AddressLine1>
<b:AddressType>Physical</b:AddressType>
<b:City>Some City</b:City>
<b:PostalCode>9999</b:PostalCode>
<b:Province>Some Province</b:Province>
<b:Suburb>Some Suburb</b:Suburb>
</b:AddressItem>
</b:Addresses>
我试图通过简单地使用下面的代码来达到预期的效果,但冒号给我的问题似乎是
var xmlDoc = XDocument.Parse(requestObj);
foreach (var element in xmlDoc.Descendants())
{
if (element.Name.LocalName.StartsWith("something"))
{
//example rename element
element.Name = "request";
XNamespace b = "http://schemas.something.org/bla/07/WebServices.Stuff";
XNamespace i = "http://www.w3.org/2001/XMLSchema-instance";
//set it's attributes
element.SetAttributeValue(XNamespace.Xmlns + "b", b);
element.SetAttributeValue(XNamespace.Xmlns + "i", i);
}
}
我使用收到的错误消息(foreach (var element in xmlDoc.Descendants())
{
element.Name = "b:" + element.Name;
}
)进行了搜索,但是似乎没有一种解决方案适用于需要递归重命名的元素。
答案 0 :(得分:1)
假设<Addresses>
是XML文档中的某些嵌套元素,并且某些上层节点应声明一个命名空间xmlns:b="http://schemas.something.org/bla/07/WebServices.Stuff"
,则可以按如下所示修改XML:
XNamespace newNamespace = "http://schemas.something.org/bla/07/WebServices.Stuff";
// Move Addresses elements and children into the new namespace
foreach (var e in xmlDoc.Descendants().Where(a => a.Name.LocalName == "Addresses").SelectMany(a => a.DescendantsAndSelf()))
{
e.Name = newNamespace + e.Name.LocalName;
}
// Optionally assign the namespace prefix "b" to some container element in scope.
xmlDoc.Root.SetAttributeValue(XNamespace.Xmlns + "b", newNamespace.NamespaceName);
注意:
您正在尝试将所选Name
对象的XElement
属性修改为"b:"+element.Name;
,但是XElement.Name
不是string
,它是是XName
,其中封装了XML名称空间和本地名称-而不是XML名称空间前缀和本地名称。因此,尝试为Name
分配一个特定的前缀会失败,并引发异常。
在LINQ-to-XML中,XElement
对象不知道其名称空间前缀。他们知道他们的实际名称空间。只有在将XElement
输出到XML字符串时,XmlWriter
才会尝试通过在范围内寻找xmlns declaration来确定名称空间前缀-否则,如果它不在范围内,它将发出一个适当的名称自动在当前元素上进行xmlns
声明。
因此,要将元素修改为类似于<b:Addresses>
的元素,必须将其实际名称空间修改为b:
应该对应的内容。现在,您可能并不在乎所选择的精确前缀,但是如果您这样做了,则可以随后在范围中的某个适当元素(例如根元素)上指定一个。
演示小提琴#1 here。
如果您不关心所使用的特定前缀,则可以完全省略// Optionally
代码,.Net的XmlWriter
将自动为您添加名称空间声明。
演示小提琴#2 here。