2009-04-04 13 views
1

내가 뭔가를 보이는 XML (XAML) 문자열이 접두사 :이름 바꾸기 XML 네임 스페이스

<Zot xmlns="clr-namespace:A.B;assembly=A" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
</Zot> 

실버 라이트 XamlReader 클래스, 그것은 특정 기본 네임 스페이스이 문자열을로드 할 수 없습니다 필요가있다 :

<z:Zot 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:z="clr-namespace:A.B;assembly=A" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
</z:Zot> 

(WPF XamlReader는이 성가신 동작을 표시하지 않습니다.)

원본 형식의 XML 문자열은 원래 형식으로 데이터베이스에 저장됩니다. 나는 그들을 후자의 형태로 변형시키고 그것을 문자열로 직렬화하는 방법이 필요하다.

이 작업을 수행하는 가장 간단한 방법에 대한 제안이 있으십니까?

답변

0

많은 도움이되지는 않지만 독자가 근본적으로 문제가있는 것처럼 보입니다. 사용 된 이름 공간 접두어는 속성 값이 QNAm 인 경우 올바르게 바인드되어야한다는 점을 제외하면 중요하지 않습니다.

0

도움이 될 수 있습니다.

using System; 
    using System.Linq; 
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Xml; 
    using System.Xml.Linq; 

    public class MainClass 
    { 
     public static void Main() 
     { 
      XNamespace nameSpace = "http://www.microsoft.com"; 

      XElement xBooks = new XElement(nameSpace + "Books", 
       new XAttribute(XNamespace.Xmlns + "linqdev", nameSpace), 
      new XElement(nameSpace + "BookParticipant")); 

      XmlDocument xdoc = new XmlDocument(); 
      xdoc.LoadXml(xBooks.ToString()); 
      xdoc.Save("c:\\xmloutput.xml"); 

     } 
    } 

이 출력합니다 (을 XmlDocument 라인이 실제로 필요하지 않습니다 불구을 XmlDocument의 xdoc에서, 난 그냥 사용을 보여주기 위해 예제를 포함) 것 :

<linqdev:Books xmlns:linqdev="http://www.microsoft.com"> 
    <linqdev:BookParticipant /> 
</linqdev:Books> 

당신은 몇 가지 XML을 사용할 수 있습니다 기술을 읽고 원래 문자열에서 다른 네임 스페이스를 제거한 다음 위의 기술을 사용하여 새 문자열을 만듭니다.

0

가장 좋은 것은 기본 xmlns 특성을 가진 요소에 다른 네임 스페이스 접두사가있는 스타일 시트였습니다. 이는 내 문서에 여러 xmlns = "..."속성이 있기 때문에 트리 아래로 재귀 적으로 적용됩니다.

<?xml version="1.0" encoding="UTF-8"?> 

<xsl:stylesheet 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:ms="urn:schemas-microsoft-com:xslt" 
    > 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>  

    <xsl:variable name="root_default_ns" select="namespace-uri(/*)" /> 

    <xsl:template match="node()|text()"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates select="node() | text()"/> 
     </xsl:copy> 
    </xsl:template> 


    <xsl:template match="*"> 
     <xsl:param name="old_default_ns" select="$root_default_ns"/> 
     <xsl:param name="new_default_ns" /> 

     <!-- match any element in the source default namespace --> 
    <xsl:if test="namespace-uri() = $old_default_ns"> 
      <xsl:element name="ns_{$new_default_ns}:{local-name()}" namespace="{$old_default_ns}"> 
       <xsl:copy-of select="@*"/> 
       <xsl:apply-templates select="node() | text()"> 
        <xsl:with-param name="old_default_ns" select="$old_default_ns" /> 
        <xsl:with-param name="new_default_ns" select="$new_default_ns" /> 
      </xsl:apply-templates> 
      </xsl:element> 
     </xsl:if> 

     <!-- match any element with a prefix qualified namespace --> 
     <xsl:if test="namespace-uri() != $old_default_ns and contains(name(), ':')"> 
      <xsl:element name="{name()}" namespace="{namespace-uri()}"> 
       <xsl:copy-of select="@*"/> 
       <xsl:apply-templates select="node() | text()"> 
        <xsl:with-param name="old_default_ns" select="$old_default_ns" /> 
        <xsl:with-param name="new_default_ns" select="$new_default_ns" /> 
      </xsl:apply-templates> 
      </xsl:element> 
    </xsl:if> 

     <!-- match any element *without* a prefix qualified namespace --> 
     <xsl:if test="namespace-uri() != $old_default_ns and contains(name(), ':') = false"> 
     <xsl:variable name="new_ns" select="count(ancestor::*)" /> 

      <xsl:element name="ns_{$new_ns}:{name()}" namespace="{namespace-uri()}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" > 
       <xsl:copy-of select="@*"/> 
       <xsl:apply-templates select="node() | text()"> 
        <xsl:with-param name="old_default_ns" select="namespace-uri()" /> 
        <xsl:with-param name="new_default_ns"><xsl:value-of select="$new_ns" /></xsl:with-param> 
      </xsl:apply-templates> 
      </xsl:element> 
     </xsl:if> 

    </xsl:template> 

    <!-- match root element only, and inject Silverlight namespace --> 
    <xsl:template match="/*"> 
     <xsl:element name="ns_root:{local-name()}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" namespace="{$root_default_ns}"> 
      <!-- inject the Silverligth ns --> 
     <xsl:variable name="dummy"> 
      <Dummy/> 
     </xsl:variable> 
     <xsl:copy-of select="ms:node-set($dummy)/*/namespace::*"/> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates select="node() | text()"> 
      <xsl:with-param name="old_default_ns" select="$root_default_ns" /> 
      <xsl:with-param name="new_default_ns">root</xsl:with-param> 
     </xsl:apply-templates> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

불행하게도,이 후프 통해 점프 후 I는 지금 XAML 문자열을 얻을 : 내 XSL 기술은 주로 구글을 기반으로 비록 다른 사람에게 유용한 경우

, 여기가 ...입니다 XamlReader가 예상하는 규칙을 따르지 만 대신 System.ExecutionEngineException을 생성합니다 (WPF XamlReader는 여전히 문자열을 올바르게 처리합니다).

1

여기 내 균열은 Python SAX 필터를 사용합니다.

 
import sys, string 

from xml.sax import saxutils, handler, make_parser 

firstElement = True 

class ContentGenerator(handler.ContentHandler): 

    def __init__(self, out = sys.stdout): 
     handler.ContentHandler.__init__(self) 
     self._out = out 

    def startDocument(self): 
     pass 

    def startElement(self, name, attrs): 
     global firstElement 
     if firstElement: 
      attrs = dict(attrs) 
      name = "z:" + name 
      if 'xmlns' in attrs: 
       attrs['xmlns:z'] = attrs['xmlns'] 
      attrs['xmlns'] = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      firstElement = False 
     elif ':' not in name: 
      name = "z:" + name 
     self._out.write('<' + name) 
     for (name, value) in attrs.items(): 
      self._out.write(' %s="%s"' % (name, saxutils.escape(value))) 
     self._out.write('>') 

    def endElement(self, name): 
     if ':' not in name: 
      name = "z:" + name 
     self._out.write('</%s>' % name) 

    def characters(self, content): 
     self._out.write(saxutils.escape(content)) 

    def ignorableWhitespace(self, content): 
     self._out.write(content) 

    def processingInstruction(self, target, data): 
     self._out.write('<?%s %s?>' % (target, data)) 

parser = make_parser() 
parser.setContentHandler(ContentGenerator()) 
parser.parse(sys.argv[1]) 

그것은 첫 번째 요소에 점프의 속성 주위 청소부, 그리고 문서의 나머지 부분에서 기본 네임 스페이스의 모든 요소를 ​​찾고 계속합니다. 그러나 문서에 여러 xmlns = ""속성이 주위에 뿌려져 있다는 의견은 도움이 필요하다는 것을 의미합니다. 일반적인 기술은 그렇게 나쁘지 않습니다. SAX 파이프 라인은 우리의 친구입니다 :-).