.NET의 XmlDocument 출력에서 ​​빈 xmlns 속성을 방지하는 방법은 무엇입니까?


118

.NET의 XmlDocument에서 XML을 생성 할 때 연결된 네임 스페이스가 없는xmlns 요소가 처음 삽입 때 빈 특성이 나타납니다 . 어떻게 예방할 수 있습니까?

예:

XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root",
    "whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner"));
Console.WriteLine(xml.OuterXml);

산출:

<root xmlns="whatever:name-space-1.0"><loner xmlns="" /></root>

원하는 출력 :

<root xmlns="whatever:name-space-1.0"><loner /></root>

문서를 문자열로 변환 한 XmlDocument 발생하는 것이 아니라 코드에 적용 가능한 솔루션 이 있습니까?OuterXml

이 작업을 수행하는 이유는 XmlDocument 생성 XML을 사용하여 특정 프로토콜의 표준 XML과 일치 할 수 있는지 확인하는 것입니다. 빈 xmlns속성 파서를 중단하거나 혼동하지 않을 있지만이 프로토콜에 대해 본 어떤 용도에도 존재하지 않습니다.

답변:


111

Jeremy Lew의 답변과 좀 더 많은 작업 덕분에 빈 xmlns속성 을 제거하는 방법을 알아 냈습니다 . 접두사를 사용 하지 않으려는 자식 노드를 만들 때 루트 노드의 네임 스페이스를 전달 합니다. 루트에서 접두사없이 네임 스페이스를 사용한다는 것은 자식 요소 에도 접두사를 갖지 않도록 동일한 네임 스페이스를 사용해야 함을 의미합니다 .

고정 코드 :

XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root", "whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner", "whatever:name-space-1.0")); 
Console.WriteLine(xml.OuterXml);

저를 올바른 방향으로 인도 한 모든 답변에 감사드립니다!


1
정확합니다. "whatever : name-space-1.0"네임 스페이스에 <loner> 요소를 넣는 것은 직렬화 될 때 빈 xmlns 속성 (네임 스페이스에 넣지 않음)이 추가되지 않음을 의미합니다. 어떻게 네임 스페이스 작업 상쾌 필요가있는 경우, 한 번 봐 가지고 jclark.com/xml/xmlns.htm
JeniT

2
조심하십시오 : 요소는 이것이 필요합니다 (또는 아마도 더 좋을 것입니다 doc.DocumentElement.NamespaceURI).하지만 네임 스페이스를 지정하지 마십시오 . 동일한 URI 인 경우에도 CreateAttribute()얻을 수 xmlns:psomething있습니다.
Jason Kleban 2015

87

이것은 JeniT의 답변의 변형입니다 (정말 감사합니다 btw!)

XmlElement new_element = doc.CreateElement("Foo", doc.DocumentElement.NamespaceURI);

이렇게하면 모든 곳에서 네임 스페이스를 복사하거나 반복 할 필요가 없습니다.


3
나에 따르면 최고의 응답. 문서 기본 네임 스페이스가 무엇인지 알 필요가 없습니다 (즉, 읽기 및 수정 시나리오에서 처음부터 xml 파일을 만들지 않을 때 유용합니다).
MuiBienCarlota

11

<loner>샘플 XML 의 요소에 xmlns기본 네임 스페이스 선언 이없는 경우 whatever:name-space-1.0네임 스페이스가 아닌 네임 스페이스에 있습니다. 이것이 원하는 경우 해당 네임 스페이스에 요소를 만들어야합니다.

xml.CreateElement("loner", "whatever:name-space-1.0")

당신이 원하는 경우 <loner>요소가없는 네임 스페이스로, 다음 생산 된 년대 XML하실 것을 적극, 당신은 걱정하지 말아야 xmlns당신을 위해 자동으로 추가 된 속성.


3
문제는 xmnls = ""에 대처할 수없는 비 호환 XML 파서 (일반적으로 Microsoft에서 제공)에 있습니다.
Craig Trader

2
/. 전화. 그들은 임의의 MS 배싱 코멘트를 원합니다.

@W. Craig Trader-문제가 발생했다고 말할 수 없습니다. 예?
Kev

1
맞습니다. <loner /> 노드에 네임 스페이스가 포함되는 것을 원하지 않지만 빈 네임 스페이스 속성 (xmlns)도 포함하고 싶지 않습니다. 내 추론은 이와 같이 설정된 특정 프로토콜의 XML 출력과 일치시킬 수 있는지 확인하는 것입니다.
Neil C. Obremski

5
무작위 강타가 아니었다. Microsoft Updater 응용 프로그램 블록은 XML 매니페스트를 사용하여 클라이언트에 전달할 내용을 결정합니다. 불행히도 Manifest 파서는 xmlns = ""에 대처할 수 없습니다. 빈 xmlns 속성을 제거하는 포스트 프로세서를 작성해야했습니다.
Craig Trader

7

루트가 접두사가없는 네임 스페이스에 있기 때문에 네임 스페이스를 제거하려는 루트의 자식은 예제와 같이 출력되어야합니다. 해결책은 다음과 같이 루트 요소를 접두사로 지정하는 것입니다.

<w:root xmlns:w="whatever:name-space-1.0">
   <loner/>
</w:root>

암호:

XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement( "w", "root", "whatever:name-space-1.0" );
doc.AppendChild( root );
root.AppendChild( doc.CreateElement( "loner" ) );
Console.WriteLine(doc.OuterXml);

감사합니다.하지만 실제 루트에 네임 스페이스를 추가하면 작업중인 특정 프로토콜과 관련하여 XML이 손상됩니다.
Neil C. Obremski

아! 나는 당신이 말하는 것을 더 많이 깨닫고 내 대답을 쓸 때 그것을 고려했습니다. 감사합니다 Jeremy
Neil C. Obremski

0

가능하면 직렬화 클래스를 만든 다음 다음을 수행하십시오.

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer serializer = new XmlSerializer(yourType);
serializer.Serialize(xmlTextWriter, someObject, ns);

더 안전하며 더 많은 제어가 필요한 경우 속성을 사용하여 네임 스페이스를 제어 할 수 있습니다.


0

Factory Pattern을 사용하여 문제를 해결했습니다. XElement 개체에 대한 팩토리를 만들었습니다. 팩토리 인스턴스화를위한 매개 변수로 XNamespace 객체를 지정했습니다. 따라서 공장에서 XElement를 만들 때마다 네임 스페이스가 자동으로 추가됩니다. 다음은 공장 코드입니다.

internal class XElementFactory
{
    private readonly XNamespace currentNs;

    public XElementFactory(XNamespace ns)
    {
        this.currentNs = ns;
    }

    internal XElement CreateXElement(String name, params object[] content)
    {
        return new XElement(currentNs + name, content);
    }
}

1
OP가 XmlDocument아니라 에 대해 묻고 있었다 XDocument.
John Saunders

0

예, XmlElement에서 XMLNS를 방지 할 수 있습니다. 첫 창조 시간이 다가오고 있습니다 : 그렇게

<trkpt lat="30.53597" lon="-97.753324" xmlns="">
    <ele>249.118774</ele>
    <time>2006-05-05T14:34:44Z</time>
</trkpt>

코드 변경 : 그리고 다음과 같이 xml 네임 스페이스를 전달합니다.

C # 코드 :

XmlElement bookElement = xdoc.CreateElement("trkpt", "http://www.topografix.com/GPX/1/1");
bookElement.SetAttribute("lat", "30.53597");
bookElement.SetAttribute("lon", "97.753324");
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.