views:

285

answers:

1

I have an XML document that I generate from an Entity Framework object. The generated XML looks like this:

REPOSTED FULL XML

<Task z:Id="i1" xmlns="http://schemas.datacontract.org/2004/07/MCC.DAL" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/"&gt;
  <EntityKey z:Id="i2" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" 
             xmlns:a="http://schemas.datacontract.org/2004/07/System.Data"&gt;
    <a:EntityContainerName>Editorial_MasterEntities</a:EntityContainerName>
    <a:EntityKeyValues>
      <a:EntityKeyMember>
        <a:Key>TaskID</a:Key>
        <a:Value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema"&gt;1670&lt;/a:Value&gt;
      </a:EntityKeyMember>
    </a:EntityKeyValues>
    <a:EntitySetName>Task</a:EntitySetName>
  </EntityKey>
  <FormCOIAns i:nil="true" />
  <FormCOIAnsReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
    <a:EntityKey i:nil="true" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" />
  </FormCOIAnsReference>
  <FormCrownLicAns z:Id="i3">
    <EntityKey z:Id="i4" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:a="http://schemas.datacontract.org/2004/07/System.Data"&gt;
      <a:EntityContainerName>Editorial_MasterEntities</a:EntityContainerName>
      <a:EntityKeyValues>
        <a:EntityKeyMember>
          <a:Key>TaskID</a:Key>
          <a:Value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema"&gt;1670&lt;/a:Value&gt;
        </a:EntityKeyMember>
      </a:EntityKeyValues>
      <a:EntitySetName>FormCrownLicAns</a:EntitySetName>
    </EntityKey>
    <CrownAgreement>1</CrownAgreement>
    <GovernmentAgency>ASDSADSADSADSA</GovernmentAgency>
    <Task z:Ref="i1" />
    <TaskID>1670</TaskID>
    <TaskReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
      <a:EntityKey z:Ref="i2" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" />
    </TaskReference>
  </FormCrownLicAns>
  <FormCrownLicAnsReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
    <a:EntityKey z:Ref="i4" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" />
  </FormCrownLicAnsReference>
  <FormStdLicAns i:nil="true" />
  <FormStdLicAnsReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
    <a:EntityKey i:nil="true" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" />
  </FormStdLicAnsReference>
  <FormType i:nil="true" />
  <FormTypeReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
    <a:EntityKey z:Id="i5" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data"&gt;
      <b:EntityContainerName>Editorial_MasterEntities</b:EntityContainerName>
      <b:EntityKeyValues>
        <b:EntityKeyMember>
          <b:Key>FormType_ID</b:Key>
          <b:Value i:type="c:int" xmlns:c="http://www.w3.org/2001/XMLSchema"&gt;3&lt;/b:Value&gt;
        </b:EntityKeyMember>
      </b:EntityKeyValues>
      <b:EntitySetName>FormType</b:EntitySetName>
    </a:EntityKey>
  </FormTypeReference>
  <LastModified i:nil="true" />
  <Manuscript z:Id="i6">
    <EntityKey z:Id="i7" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:a="http://schemas.datacontract.org/2004/07/System.Data"&gt;
      <a:EntityContainerName>Editorial_MasterEntities</a:EntityContainerName>
      <a:EntityKeyValues>
        <a:EntityKeyMember>
          <a:Key>ManuscriptID</a:Key>
          <a:Value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema"&gt;3000004&lt;/a:Value&gt;
        </a:EntityKeyMember>
        <a:EntityKeyMember>
          <a:Key>PubID</a:Key>
          <a:Value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema"&gt;3&lt;/a:Value&gt;
        </a:EntityKeyMember>
      </a:EntityKeyValues>
      <a:EntitySetName>Manuscript</a:EntitySetName>
    </EntityKey>
    <Editor i:nil="true" />
    <EditorReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
      <a:EntityKey z:Id="i8" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data"&gt;
        <b:EntityContainerName>Editorial_MasterEntities</b:EntityContainerName>
        <b:EntityKeyValues>
          <b:EntityKeyMember>
            <b:Key>EditorID</b:Key>
            <b:Value i:type="c:int" xmlns:c="http://www.w3.org/2001/XMLSchema"&gt;3&lt;/b:Value&gt;
          </b:EntityKeyMember>
        </b:EntityKeyValues>
        <b:EntitySetName>Editor</b:EntitySetName>
      </a:EntityKey>
    </EditorReference>
    <ManuscriptID>3000004</ManuscriptID>
    <ManuscriptStatus i:nil="true" />
    <ManuscriptStatusReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
      <a:EntityKey i:nil="true" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" />
    </ManuscriptStatusReference>
    <PubID>3</PubID>
    <Publication i:nil="true" />
    <PublicationReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
      <a:EntityKey z:Id="i9" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data"&gt;
        <b:EntityContainerName>Editorial_MasterEntities</b:EntityContainerName>
        <b:EntityKeyValues>
          <b:EntityKeyMember>
            <b:Key>PubID</b:Key>
            <b:Value i:type="c:int" xmlns:c="http://www.w3.org/2001/XMLSchema"&gt;3&lt;/b:Value&gt;
          </b:EntityKeyMember>
        </b:EntityKeyValues>
        <b:EntitySetName>Publication</b:EntitySetName>
      </a:EntityKey>
    </PublicationReference>
    <Task>
      <Task z:Ref="i1" />
    </Task>
    <Title>test</Title>
  </Manuscript>
  <ManuscriptReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
    <a:EntityKey z:Ref="i7" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" />
  </ManuscriptReference>
  <MasterPerson z:Id="i10">
    <EntityKey z:Id="i11" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:a="http://schemas.datacontract.org/2004/07/System.Data"&gt;
      <a:EntityContainerName>Editorial_MasterEntities</a:EntityContainerName>
      <a:EntityKeyValues>
        <a:EntityKeyMember>
          <a:Key>MPID</a:Key>
          <a:Value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema"&gt;1380007&lt;/a:Value&gt;
        </a:EntityKeyMember>
      </a:EntityKeyValues>
      <a:EntitySetName>MasterPerson</a:EntitySetName>
    </EntityKey>
    <Comments i:nil="true" />
    <Created>2008-01-08T14:14:01.867</Created>
    <Do_Not_Use>false</Do_Not_Use>
    <Editor />
    <FName>tony</FName>
    <LName>kim</LName>
    <MName />
    <MPGUID>C6C28CFFD41A4106B3FDB4CFBBF79B63</MPGUID>
    <MPID>1380007</MPID>
    <Prefix i:nil="true" />
    <Suffix i:nil="true" />
    <Task>
      <Task z:Ref="i1" />
    </Task>
    <Updated>2008-01-08T14:14:01.867</Updated>
  </MasterPerson>
  <MasterPersonReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
    <a:EntityKey z:Ref="i11" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" />
  </MasterPersonReference>
  <TaskID>1670</TaskID>
  <TaskStatus z:Id="i12">
    <EntityKey z:Id="i13" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:a="http://schemas.datacontract.org/2004/07/System.Data"&gt;
      <a:EntityContainerName>Editorial_MasterEntities</a:EntityContainerName>
      <a:EntityKeyValues>
        <a:EntityKeyMember>
          <a:Key>TaskStatusID</a:Key>
          <a:Value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema"&gt;3&lt;/a:Value&gt;
        </a:EntityKeyMember>
      </a:EntityKeyValues>
      <a:EntitySetName>TaskStatus</a:EntitySetName>
    </EntityKey>
    <Description>Completed</Description>
    <Task>
      <Task z:Ref="i1" />
    </Task>
    <TaskStatusID>3</TaskStatusID>
  </TaskStatus>
  <TaskStatusReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"&gt;
    <a:EntityKey z:Ref="i13" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" />
  </TaskStatusReference>
</Task>

This was the stylesheet that was working yesterday, but evidently something changed in my XML - you can see the comps with the local-name vs. XPath.

    <?xml version='1.0'?>
    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/"
      xmlns:c="http://www.w3.org/2001/XMLSchema"
      xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"
      xmlns:b="http://schemas.datacontract.org/2004/07/System.Data"
      xmlns="http://schemas.datacontract.org/2004/07/MCC.DAL"&gt;
      <!--xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" -->

      <xsl:template match="/*">
        <DIV STYLE="font-weight:bold">
          Local name:<xsl:value-of select="/*[local-name()='Task']/*[local-name()='MasterPerson']/*[local-name()='FName']" /><br />
          XPath:<xsl:value-of select="/Task/MasterPerson/FName"/>
        </DIV>
      </xsl:template>
    </xsl:stylesheet>

The problem I'm having listing out the namespaces is that some of them overlap based on the tag-level context, so that could be the resulting problem. Evidently yesterday I was using a different source XML (argh) or just a different object set altogether. (Either way, if the source changes it shouldn't blow up the XSLT like this.)

Right now I'm relegated to using the local-name() approach throughout, but really would like to figure this out. TIA.

+2  A: 

Tentatively... Sorry I haven't time to test that the following works...

EDIT (finishing after a long day at work...) Yes! That was about right. t'was only missing a * for the template match string, which should be "/*" not just "/"

This tested ok with an XML file made by copying that from the OP's question (with necessary edits since the sample XML of the question is fragmentary). Attention, however! Using the *[local-name()='xyz'] trick to ignore namespaces should be kept for quick tests, read after the code snippet for a preferable way of handling these XML Namespaces.

  <xsl:template match="/">
    <DIV STYLE="font-weight:bold">
      <xsl:value-of select="*[local-name()='Task']/*[local-name()='MasterPerson']/*[local-name()='FName']" />
    </DIV>
  </xsl:template>

XPath and Namespaces

The XPath data model treats an XML document as a tree of nodes, such as element, attribute, and text nodes, where the name of each node is a combination of its local name and its namespace name. Interestingly XPath deals with the default namespace in a way that is inconsistent, and that is why one doesn't notice all this xmlns issue until elements targeted by the XSL belong to fully qualified named elements in the input XML.... see this link for more details.

When faced with XML input that has xmlns-specified elements, an XSL script writer must either ensure to fully qualify its target nodes' names (preferred approach) or use the local-name() trick shown above to instruct XPath to ignore the namespaces. To use xmlns-prefixed names, a short prefix can be defined as usually and it can then be used by the XSL logic, as follows. (actual xmlns may be wrong, as the sample xml file is incomplete)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:t="http://schemas.datacontract.org/2004/07/MCC.DAL"&gt;

 <xsl:template match="/MyRoot">
    <DIV STYLE="font-weight:bold">
      <xsl:value-of select="t:Task/i:MasterPerson/i:FName" />
    </DIV>
  </xsl:template>
</xsl:stylesheet>
mjv
The local-name() approach works for me if I add a "/" before the expression.What are the downsides to using the local-name approach? Just curious... I'm going to see if I can add all these namespaces to my XSLT, stay tuned. Thanks!CP
CP
Right, the / may be needed, depending on the XML input. The downside to ignoring the namespace (with the local-name approach): the XPath expression(s) that use them is less precise, possibly matching "wrong" nodes that happen to have the same name in another namespace, or not allowing you to express the same kind of specificity for example in the selectors such as these that involve node attributes (@ thing) and such. In a nutshell your XPath expression is at best longer and more arcane, and at worse a bit less specific, possibly matching undesired targets.
mjv