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

.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속성 파서를 중단하거나 혼동하지 않을 있지만이 프로토콜에 대해 본 어떤 용도에도 존재하지 않습니다.



답변

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);

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


답변

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

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

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


답변

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

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

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


답변

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

<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);


답변

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

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

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


답변

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);
    }
}


답변

예, 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");